@chronodivide/game-api 0.74.0 → 0.76.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,13 +1,13 @@
1
- import*as __WEBPACK_EXTERNAL_MODULE_three__ from"three";import*as __WEBPACK_EXTERNAL_MODULE_fetch_blob_71f8024a__ from"fetch-blob";import*as __WEBPACK_EXTERNAL_MODULE_websocket_polyfill_8396782d__ from"websocket-polyfill";import{createRequire as __WEBPACK_EXTERNAL_createRequire}from"node:module";const __WEBPACK_EXTERNAL_createRequire_require=__WEBPACK_EXTERNAL_createRequire(import.meta.url);import*as __WEBPACK_EXTERNAL_MODULE_es_dirname_044d89a0__ from"es-dirname";import*as __WEBPACK_EXTERNAL_MODULE_file_system_access_58c08c7f__ from"file-system-access";import*as __WEBPACK_EXTERNAL_MODULE_file_system_access_lib_adapters_node_js_b1c03fd5__ from"file-system-access/lib/adapters/node.js";var __webpack_modules__={70(e){e.exports=__WEBPACK_EXTERNAL_MODULE_three__},370(l,h,c){var u;!function(){"use strict";function e(e,t){return function(){return t.apply(e,arguments)}}function i(){for(var e,t=arguments,i=t[0],r=1;r<t.length;r++)for(e in t[r])e in i||!t[r].hasOwnProperty(e)||(i[e]=t[r][e]);return i}var r,o={VERSION:"1.4.1"},s={},t=function(e,t){return{value:e,name:t}};o.DEBUG=t(1,"DEBUG"),o.INFO=t(2,"INFO"),o.TIME=t(3,"TIME"),o.WARN=t(4,"WARN"),o.ERROR=t(8,"ERROR"),o.OFF=t(99,"OFF");function a(e){this.context=e,this.setLevel(e.filterLevel),this.log=this.info}a.prototype={setLevel:function(e){e&&"value"in e&&(this.context.filterLevel=e)},getLevel:function(){return this.context.filterLevel},enabledFor:function(e){var t=this.context.filterLevel;return e.value>=t.value},debug:function(){this.invoke(o.DEBUG,arguments)},info:function(){this.invoke(o.INFO,arguments)},warn:function(){this.invoke(o.WARN,arguments)},error:function(){this.invoke(o.ERROR,arguments)},time:function(e){"string"==typeof e&&0<e.length&&this.invoke(o.TIME,[e,"start"])},timeEnd:function(e){"string"==typeof e&&0<e.length&&this.invoke(o.TIME,[e,"end"])},invoke:function(e,t){r&&this.enabledFor(e)&&r(t,i({level:e},this.context))}};var n=new a({filterLevel:o.OFF});(t=o).enabledFor=e(n,n.enabledFor),t.debug=e(n,n.debug),t.time=e(n,n.time),t.timeEnd=e(n,n.timeEnd),t.info=e(n,n.info),t.warn=e(n,n.warn),t.error=e(n,n.error),t.log=t.info,o.setHandler=function(e){r=e},o.setLevel=function(e){for(var t in n.setLevel(e),s)s.hasOwnProperty(t)&&s[t].setLevel(e)},o.getLevel=function(){return n.getLevel()},o.get=function(e){return s[e]||(s[e]=new a(i({name:e},n.context)))},o.createDefaultHandler=function(s){(s=s||{}).formatter=s.formatter||function(e,t){t.name&&e.unshift("["+t.name+"]")};function a(e,t){Function.prototype.apply.call(e,console,t)}var n={};return"undefined"==typeof console?function(){}:function(e,t){e=Array.prototype.slice.call(e);var i,r=console.log;t.level===o.TIME?(i=(t.name?"["+t.name+"] ":"")+e[0],"start"===e[1]?console.time?console.time(i):n[i]=(new Date).getTime():console.timeEnd?console.timeEnd(i):a(r,[i+": "+((new Date).getTime()-n[i])+"ms"])):(t.level===o.WARN&&console.warn?r=console.warn:t.level===o.ERROR&&console.error?r=console.error:t.level===o.INFO&&console.info?r=console.info:t.level===o.DEBUG&&console.debug&&(r=console.debug),s.formatter(e,t),a(r,e))}},o.useDefaults=function(e){o.setLevel(e&&e.defaultLevel||o.DEBUG),o.setHandler(o.createDefaultHandler(e))},void 0===(u="function"==typeof(u=o)?u.call(h,c,h,l):u)||(l.exports=u)}()},422(e){e.exports=__WEBPACK_EXTERNAL_MODULE_fetch_blob_71f8024a__},804(e){function t(e){null==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,e.constructor==Array?this.init_by_array(e,e.length):this.init_seed(e)}t.prototype.init_seed=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},t.prototype.init_by_array=function(e,t){var i,r,s;for(this.init_seed(19650218),i=1,r=0,s=this.N>t?this.N:t;s;s--){var a=this.mt[i-1]^this.mt[i-1]>>>30;this.mt[i]=(this.mt[i]^(1664525*((4294901760&a)>>>16)<<16)+1664525*(65535&a))+e[r]+r,this.mt[i]>>>=0,r++,++i>=this.N&&(this.mt[0]=this.mt[this.N-1],i=1),t<=r&&(r=0)}for(s=this.N-1;s;s--){a=this.mt[i-1]^this.mt[i-1]>>>30;this.mt[i]=(this.mt[i]^(1566083941*((4294901760&a)>>>16)<<16)+1566083941*(65535&a))-i,this.mt[i]>>>=0,++i>=this.N&&(this.mt[0]=this.mt[this.N-1],i=1)}this.mt[0]=2147483648},t.prototype.random_int=function(){var e,t,i=new Array(0,this.MATRIX_A);if(this.mti>=this.N){for(this.mti==this.N+1&&this.init_seed(5489),t=0;t<this.N-this.M;t++)e=this.mt[t]&this.UPPER_MASK|this.mt[t+1]&this.LOWER_MASK,this.mt[t]=this.mt[t+this.M]^e>>>1^i[1&e];for(;t<this.N-1;t++)e=this.mt[t]&this.UPPER_MASK|this.mt[t+1]&this.LOWER_MASK,this.mt[t]=this.mt[t+(this.M-this.N)]^e>>>1^i[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^i[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},t.prototype.random_int31=function(){return this.random_int()>>>1},t.prototype.random_incl=function(){return this.random_int()*(1/4294967295)},t.prototype.random=function(){return this.random_int()*(1/4294967296)},t.prototype.random_excl=function(){return(this.random_int()+.5)*(1/4294967296)},t.prototype.random_long=function(){return 1/9007199254740992*(67108864*(this.random_int()>>>5)+(this.random_int()>>>6))},e.exports=t},887(e,t,i){i.r(t),i.d(t,{default:()=>r});const r=function(){"use strict";var i=new function(){this.blockSize=131072,this.minNewSize=this.blockSize,this.maxSize=0,this.OK=0,this.INPUT_OVERRUN=-4,this.OUTPUT_OVERRUN=-5,this.LOOKBEHIND_OVERRUN=-6,this.EOF_FOUND=-999,this.ret=0,this.buf=null,this.buf32=null,this.out=new Uint8Array(262144),this.cbl=0,this.ip_end=0,this.op_end=0,this.t=0,this.ip=0,this.op=0,this.m_pos=0,this.m_len=0,this.m_off=0,this.dv_hi=0,this.dv_lo=0,this.dindex=0,this.ii=0,this.jj=0,this.tt=0,this.v=0,this.dict=new Uint32Array(16384),this.emptyDict=new Uint32Array(16384),this.skipToFirstLiteralFun=!1,this.returnNewBuffers=!0,this.setBlockSize=function(e){return"number"==typeof e&&!isNaN(e)&&0<parseInt(e)&&(this.blockSize=parseInt(e),!0)},this.setOutputSize=function(e){return"number"==typeof e&&!isNaN(e)&&0<parseInt(e)&&(this.out=new Uint8Array(parseInt(e)),!0)},this.setReturnNewBuffers=function(e){this.returnNewBuffers=!!e},this.applyConfig=function(e){void 0!==e&&(void 0!==e.outputSize&&i.setOutputSize(e.outputSize),void 0!==e.blockSize&&i.setBlockSize(e.blockSize))},this.ctzl=function(e){var t;return 1&e?t=0:(t=1,0==(65535&e)&&(e>>=16,t+=16),0==(255&e)&&(e>>=8,t+=8),0==(15&e)&&(e>>=4,t+=4),0==(3&e)&&(e>>=2,t+=2),t-=1&e),t},this.extendBuffer=function(){var e=new Uint8Array(this.minNewSize+(this.blockSize-this.minNewSize%this.blockSize));e.set(this.out),this.out=e,this.cbl=this.out.length},this.match_next=function(){this.minNewSize=this.op+3,this.minNewSize>this.cbl&&this.extendBuffer(),this.out[this.op++]=this.buf[this.ip++],1<this.t&&(this.out[this.op++]=this.buf[this.ip++],2<this.t&&(this.out[this.op++]=this.buf[this.ip++])),this.t=this.buf[this.ip++]},this.match_done=function(){return this.t=3&this.buf[this.ip-2],this.t},this.copy_match=function(){for(this.t+=2,this.minNewSize=this.op+this.t,this.minNewSize>this.cbl&&this.extendBuffer();this.out[this.op++]=this.out[this.m_pos++],0<--this.t;);},this.copy_from_buf=function(){for(this.minNewSize=this.op+this.t,this.minNewSize>this.cbl&&this.extendBuffer();this.out[this.op++]=this.buf[this.ip++],0<--this.t;);},this.match=function(){for(;;){if(64<=this.t)this.m_pos=this.op-1-(this.t>>2&7)-(this.buf[this.ip++]<<3),this.t=(this.t>>5)-1,this.copy_match();else if(32<=this.t){if(this.t&=31,0===this.t){for(;0===this.buf[this.ip];)this.t+=255,this.ip++;this.t+=31+this.buf[this.ip++]}this.m_pos=this.op-1-(this.buf[this.ip]>>2)-(this.buf[this.ip+1]<<6),this.ip+=2,this.copy_match()}else if(16<=this.t){if(this.m_pos=this.op-((8&this.t)<<11),this.t&=7,0===this.t){for(;0===this.buf[this.ip];)this.t+=255,this.ip++;this.t+=7+this.buf[this.ip++]}if(this.m_pos-=(this.buf[this.ip]>>2)+(this.buf[this.ip+1]<<6),this.ip+=2,this.m_pos===this.op)return this.state.outputBuffer=!0===this.returnNewBuffers?new Uint8Array(this.out.subarray(0,this.op)):this.out.subarray(0,this.op),this.EOF_FOUND;this.m_pos-=16384,this.copy_match()}else this.m_pos=this.op-1-(this.t>>2)-(this.buf[this.ip++]<<2),this.minNewSize=this.op+2,this.minNewSize>this.cbl&&this.extendBuffer(),this.out[this.op++]=this.out[this.m_pos++],this.out[this.op++]=this.out[this.m_pos];if(0===this.match_done())return this.OK;this.match_next()}},this.decompress=function(e){if(this.state=e,this.buf=this.state.inputBuffer,this.cbl=this.out.length,this.ip_end=this.buf.length,this.t=0,this.ip=0,this.op=0,this.m_pos=0,this.skipToFirstLiteralFun=!1,17<this.buf[this.ip])if(this.t=this.buf[this.ip++]-17,this.t<4){if(this.match_next(),this.ret=this.match(),this.ret!==this.OK)return this.ret===this.EOF_FOUND?this.OK:this.ret}else this.copy_from_buf(),this.skipToFirstLiteralFun=!0;for(;;){if(this.skipToFirstLiteralFun)this.skipToFirstLiteralFun=!1;else{if(this.t=this.buf[this.ip++],16<=this.t){if(this.ret=this.match(),this.ret!==this.OK)return this.ret===this.EOF_FOUND?this.OK:this.ret;continue}if(0===this.t){for(;0===this.buf[this.ip];)this.t+=255,this.ip++;this.t+=15+this.buf[this.ip++]}this.t+=3,this.copy_from_buf()}if(this.t=this.buf[this.ip++],this.t<16){if(this.m_pos=this.op-2049,this.m_pos-=this.t>>2,this.m_pos-=this.buf[this.ip++]<<2,this.minNewSize=this.op+3,this.minNewSize>this.cbl&&this.extendBuffer(),this.out[this.op++]=this.out[this.m_pos++],this.out[this.op++]=this.out[this.m_pos++],this.out[this.op++]=this.out[this.m_pos],0===this.match_done())continue;this.match_next()}if(this.ret=this.match(),this.ret!==this.OK)return this.ret===this.EOF_FOUND?this.OK:this.ret}return this.OK},this._compressCore=function(){for(this.ip_start=this.ip,this.ip_end=this.ip+this.ll-20,this.jj=this.ip,this.ti=this.t,this.ip+=this.ti<4?4-this.ti:0,this.ip+=1+(this.ip-this.jj>>5);!(this.ip>=this.ip_end);)if(this.dv_lo=this.buf[this.ip]|this.buf[this.ip+1]<<8,this.dv_hi=this.buf[this.ip+2]|this.buf[this.ip+3]<<8,this.dindex=((17053*this.dv_lo>>>16)+17053*this.dv_hi+6180*this.dv_lo&65535)>>>2,this.m_pos=this.ip_start+this.dict[this.dindex],this.dict[this.dindex]=this.ip-this.ip_start,(this.dv_hi<<16)+this.dv_lo==(this.buf[this.m_pos]|this.buf[this.m_pos+1]<<8|this.buf[this.m_pos+2]<<16|this.buf[this.m_pos+3]<<24)){if(this.jj-=this.ti,this.ti=0,this.v=this.ip-this.jj,0!==this.v)if(this.v<=3)for(this.out[this.op-2]|=this.v;this.out[this.op++]=this.buf[this.jj++],0<--this.v;);else{if(this.v<=18)this.out[this.op++]=this.v-3;else{for(this.tt=this.v-18,this.out[this.op++]=0;255<this.tt;)this.tt-=255,this.out[this.op++]=0;this.out[this.op++]=this.tt}for(;this.out[this.op++]=this.buf[this.jj++],0<--this.v;);}if(this.m_len=4,this.buf[this.ip+this.m_len]===this.buf[this.m_pos+this.m_len])for(;this.m_len+=1,this.buf[this.ip+this.m_len]===this.buf[this.m_pos+this.m_len]&&(this.m_len+=1,this.buf[this.ip+this.m_len]===this.buf[this.m_pos+this.m_len]&&(this.m_len+=1,this.buf[this.ip+this.m_len]===this.buf[this.m_pos+this.m_len]&&(this.m_len+=1,this.buf[this.ip+this.m_len]===this.buf[this.m_pos+this.m_len]&&(this.m_len+=1,this.buf[this.ip+this.m_len]===this.buf[this.m_pos+this.m_len]&&(this.m_len+=1,this.buf[this.ip+this.m_len]===this.buf[this.m_pos+this.m_len]&&(this.m_len+=1,this.buf[this.ip+this.m_len]===this.buf[this.m_pos+this.m_len]&&(this.m_len+=1,this.buf[this.ip+this.m_len]===this.buf[this.m_pos+this.m_len]&&!(this.ip+this.m_len>=this.ip_end)&&this.buf[this.ip+this.m_len]===this.buf[this.m_pos+this.m_len]))))))););if(this.m_off=this.ip-this.m_pos,this.ip+=this.m_len,this.jj=this.ip,this.m_len<=8&&this.m_off<=2048)--this.m_off,this.out[this.op++]=this.m_len-1<<5|(7&this.m_off)<<2,this.out[this.op++]=this.m_off>>3;else if(this.m_off<=16384){if(--this.m_off,this.m_len<=33)this.out[this.op++]=32|this.m_len-2;else{for(this.m_len-=33,this.out[this.op++]=32;255<this.m_len;)this.m_len-=255,this.out[this.op++]=0;this.out[this.op++]=this.m_len}this.out[this.op++]=this.m_off<<2,this.out[this.op++]=this.m_off>>6}else{if(this.m_off-=16384,this.m_len<=9)this.out[this.op++]=16|this.m_off>>11&8|this.m_len-2;else{for(this.m_len-=9,this.out[this.op++]=16|this.m_off>>11&8;255<this.m_len;)this.m_len-=255,this.out[this.op++]=0;this.out[this.op++]=this.m_len}this.out[this.op++]=this.m_off<<2,this.out[this.op++]=this.m_off>>6}}else this.ip+=1+(this.ip-this.jj>>5);this.t=this.ll-(this.jj-this.ip_start-this.ti)},this.compress=function(e){for(this.state=e,this.ip=0,this.buf=this.state.inputBuffer,this.maxSize=this.buf.length+Math.ceil(this.buf.length/16)+64+3,this.maxSize>this.out.length&&(this.out=new Uint8Array(this.maxSize)),this.op=0,this.l=this.buf.length,this.t=0;20<this.l&&(this.ll=this.l<=49152?this.l:49152,!(this.t+this.ll>>5<=0));)this.dict.set(this.emptyDict),this.prev_ip=this.ip,this._compressCore(),this.ip=this.prev_ip+this.ll,this.l-=this.ll;if(this.t+=this.l,0<this.t){if(this.ii=this.buf.length-this.t,0===this.op&&this.t<=238)this.out[this.op++]=17+this.t;else if(this.t<=3)this.out[this.op-2]|=this.t;else if(this.t<=18)this.out[this.op++]=this.t-3;else{for(this.tt=this.t-18,this.out[this.op++]=0;255<this.tt;)this.tt-=255,this.out[this.op++]=0;this.out[this.op++]=this.tt}for(;this.out[this.op++]=this.buf[this.ii++],0<--this.t;);}return this.out[this.op++]=17,this.out[this.op++]=0,this.out[this.op++]=0,this.state.outputBuffer=!0===this.returnNewBuffers?new Uint8Array(this.out.subarray(0,this.op)):this.out.subarray(0,this.op),this.OK}};return{setBlockSize:function(e){return i.setBlockSize(e)},setOutputEstimate:function(e){return i.setOutputSize(e)},setReturnNewBuffers:function(e){i.setReturnNewBuffers(e)},compress:function(e,t){return void 0!==t&&i.applyConfig(t),i.compress(e)},decompress:function(e,t){return void 0!==t&&i.applyConfig(t),i.decompress(e)}}}()}},__webpack_module_cache__={};function __webpack_require__(e){var t=__webpack_module_cache__[e];if(void 0!==t)return t.exports;t=__webpack_module_cache__[e]={exports:{}};return __webpack_modules__[e].call(t.exports,t,t.exports,__webpack_require__),t.exports}__webpack_require__.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return __webpack_require__.d(t,{a:t}),t},__webpack_require__.d=(e,t)=>{for(var i in t)__webpack_require__.o(t,i)&&!__webpack_require__.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var __webpack_exports__={};__webpack_require__.r(__webpack_exports__);const external_websocket_polyfill_namespaceObject=__WEBPACK_EXTERNAL_MODULE_websocket_polyfill_8396782d__,external_node_crypto_namespaceObject=__WEBPACK_EXTERNAL_createRequire_require("node:crypto"),external_path_namespaceObject=__WEBPACK_EXTERNAL_createRequire_require("path"),external_es_dirname_namespaceObject=__WEBPACK_EXTERNAL_MODULE_es_dirname_044d89a0__,external_file_system_access_namespaceObject=__WEBPACK_EXTERNAL_MODULE_file_system_access_58c08c7f__,node_js_namespaceObject=__WEBPACK_EXTERNAL_MODULE_file_system_access_lib_adapters_node_js_b1c03fd5__;class IniSection{constructor(e){this.entries=new Map,this.sections=new Map,this.name=e}fromJson(e){for(var t in e){var i;e.hasOwnProperty(t)&&(i=e[t],Array.isArray(i)||"object"!=typeof i?this.set(t,i):this.sections.set(t,new IniSection(t).fromJson(i)))}return this}clone(){let i=new IniSection(this.name);return this.entries.forEach((e,t)=>{i.set(t,e)}),this.sections.forEach((e,t)=>{i.sections.set(t,e.clone())}),i}set(e,t){this.entries.set(e,t)}get(e){return this.entries.get(e)}has(e){return this.entries.has(e)}getString(e,t=""){e=this.get(e);return e&&"string"==typeof e?e:t}getNumber(e,t=0){var i=this.get(e);if(!i||"string"!=typeof i)return t;var r=this.parseNumber(i);return void 0===r?(console.warn(`Invalid value for key ${e}. "${i}" is not a valid number or percentage string.`),t):r}parseNumber(e){let t;if(t=e.match(/%$/)?Number(e.replace("%",""))/100:Number(e),!isNaN(t))return t}getFixed(e,t=0){return this.toFixedPointPrecision(this.getNumber(e,t))}toFixedPointPrecision(e){return(65536*e|0)/65536}getBool(e,t=!1){let i=this.getString(e).trim();return i=i&&i.toLowerCase(),!(!i||-1===["yes","1","true","on"].indexOf(i))||(!i||-1===["no","0","false","off"].indexOf(i))&&t}getKeyArray(e,t=[]){e=this.get(e);return e&&Array.isArray(e)?e:t}getArray(e,t=/,\s*/,i=[]){let r=this.getString(e).trim();return r=r.replace(/,$/,"").replace(/,+/g,","),r?r.split(t):i}getNumberArray(e,t=/,\s*/,i=[]){let r=this.getString(e).trim();if(!r)return i;let s=[];for(var a of r.split(t)){if(!a)return i;var n=this.parseNumber(a);if(void 0===n)return console.warn(`Invalid value for key ${e}. "${a}" is not a valid number or percentage string.`),i;s.push(n)}return s}getFixedArray(e,t=/,\s*/,i=[]){return this.getNumberArray(e,t,i).map(e=>this.toFixedPointPrecision(e))}getEnum(e,t,i,r=!1){let s=this.getString(e).trim();if(!s)return i;let a;if(r){let e=Object.getOwnPropertyNames(t);r=e.find(e=>e.toLowerCase()===s.toLowerCase());r&&(a=t[r])}else t.hasOwnProperty(s)&&(a=t[s]);return void 0===a?(console.warn(`Invalid value for key "${e}". "${s}" is not an accepted enum value.`),i):a}getEnumNumeric(e,t,i){var r=this.getString(e).trim();if(!r)return i;let s;return Number.isInteger(parseInt(r,10))&&t.hasOwnProperty(r)&&(s=parseInt(r,10)),void 0===s?(console.warn(`Invalid value for key "${e}". "${r}" is not an accepted enum value.`),i):s}getEnumArray(e,r,t=/,\s*/,s=[],a=!1){let n=this.getString(e).trim();if(!n)return s;let o=[];for(let i of n.split(t)){if(!i)return s;let t=!1;if(a){let e=Object.getOwnPropertyNames(r);var l=e.find(e=>e.toLowerCase()===i.toLowerCase());l&&(o.push(r[l]),t=!0)}else r.hasOwnProperty(i)&&(o.push(r[i]),t=!0);if(!t)return console.warn(`Invalid value "${i}" for key "${e}".`),s}return o}getHighestNumericIndex(){let i=0,r;return this.entries.forEach((e,t)=>{r=parseInt(t,10),r>i&&(i=r)}),i}isNumericIndexArray(){return 0<this.getHighestNumericIndex()||this.has("0")}getConcatenatedValues(){let e="";for(var t of this.entries.values())"string"==typeof t&&(e+=t);return e}toString(e){let t=[],i=(e?e+".":"")+this.name;t.push(`[${i}]`);for(var[r,s]of this.entries)if(Array.isArray(s))for(var a of s)t.push(r+"[]="+a);else t.push(r+"="+s);return t.push(""),t.join("\r\n")+[...this.sections.values()].map(e=>e.toString(i)).join("\r\n")}mergeWith(e){if(this.isNumericIndexArray()){let i=this.getHighestNumericIndex()+1;e.entries.forEach((e,t)=>{Number.isNaN(Number(t))||Array.isArray(e)||this.set((i++).toString(),e)})}else e.entries.forEach((e,t)=>{this.set(t,Array.isArray(e)?[...e]:e)});e.sections.forEach((e,t)=>{let i=this.getOrCreateSection(t);i.mergeWith(e)})}getOrCreateSection(e){let t=this.sections.get(e);return t||(t=new IniSection(e),this.sections.set(e,t)),t}getSection(e){return this.sections.get(e)}getOrderedSections(){return[...this.sections.values()]}}class IniParser{parse(e){let a={},i=a,r,s=/^\[([^\]]*)\]\s*$|^([^=]+)(=(.*))?$/i,t=e.split(/[\r\n]+/g);return t.forEach(t=>{if(t&&!t.match(/^\s*[;#]/)){t=(t=t.replace(/]\s*(\/\/|;|#).*$/,"]")).match(s);if(t){if(void 0!==t[1])return r=this.unsafe(t[1]),void(i=a[r]=a[r]||{});let e=this.unsafe(t[2]);t=t[3]?this.unsafe(t[4]||""):"";2<e.length&&"[]"===e.slice(-2)&&(e=e.substring(0,e.length-2),i[e]?Array.isArray(i[e])||(i[e]=[i[e]]):i[e]=[]),Array.isArray(i[e])?i[e].push(t):i[e]=t}}}),Object.keys(a).filter(e=>{if(!a[e]||"object"!=typeof a[e]||Array.isArray(a[e]))return!1;let t=this.dotSplit(e),i=a,r=t.pop();var s=r.replace(/\\\./g,".");return t.forEach(function(e){i[e]&&"object"==typeof i[e]||(i[e]={}),i=i[e]}),(i!==a||s!==r)&&(i[s]=a[e],!0)}).forEach(function(e){delete a[e]}),a}dotSplit(e){return e.replace(/\x01/g,"LITERAL\\1LITERAL").replace(/\\\./g,"").split(/\./).map(e=>e.replace(/\x01/g,"\\.").replace(/\x02LITERAL\\1LITERAL\x02/g,""))}isQuoted(e){return'"'===e.charAt(0)&&'"'===e.slice(-1)||"'"===e.charAt(0)&&"'"===e.slice(-1)}unsafe(s){if(s=(s||"").trim(),this.isQuoted(s))return s=s.substr(1,s.length-2);{let i=!1,r="";for(let e=0,t=s.length;e<t;e++){var a=s.charAt(e);if(i)-1!=="\\;#".indexOf(a)?r+=a:r+="\\"+a,i=!1;else{if(-1!==";#".indexOf(a))break;"\\"===a?i=!0:r+=a}}return i&&(r+="\\"),r=r.trim(),r}}}class DataStream{constructor(e,t,i=DataStream.LITTLE_ENDIAN){this.endianness=i,this.position=0,this._dynamicSize=!0,this._byteLength=0,this._byteOffset=t||0,e instanceof ArrayBuffer?this.buffer=e:"object"==typeof e?(this.dataView=e,t&&(this._byteOffset+=t)):this.buffer=new ArrayBuffer(e||0)}get dynamicSize(){return this._dynamicSize}set dynamicSize(e){e||this._trimAlloc(),this._dynamicSize=e}get byteLength(){return this._byteLength-this._byteOffset}get buffer(){return this._trimAlloc(),this._buffer}set buffer(e){this._buffer=e,this._dataView=new DataView(this._buffer,this._byteOffset),this._byteLength=this._buffer.byteLength}get byteOffset(){return this._byteOffset}set byteOffset(e){this._byteOffset=e,this._dataView=new DataView(this._buffer,this._byteOffset),this._byteLength=this._buffer.byteLength}get dataView(){return this._dataView}set dataView(e){this._byteOffset=e.byteOffset,this._buffer=e.buffer,this._dataView=new DataView(this._buffer,this._byteOffset),this._byteLength=this._byteOffset+e.byteLength}bigEndian(){return this.endianness=DataStream.BIG_ENDIAN,this}_realloc(t){if(this._dynamicSize){var i=this._byteOffset+this.position+t;let e=this._buffer.byteLength;if(i<=e)i>this._byteLength&&(this._byteLength=i);else{for(e<1&&(e=1);i>e;)e*=2;var r=new ArrayBuffer(e),t=new Uint8Array(this._buffer);const s=new Uint8Array(r,0,t.length);s.set(t),this.buffer=r,this._byteLength=i}}}_trimAlloc(){if(this._byteLength!==this._buffer.byteLength){var e=new ArrayBuffer(this._byteLength);const i=new Uint8Array(e);var t=new Uint8Array(this._buffer,0,i.length);i.set(t),this.buffer=e}}seek(e){e=Math.max(0,Math.min(this.byteLength,e));this.position=isNaN(e)||!isFinite(e)?0:e}isEof(){return this.position>=this.byteLength}mapInt32Array(e,t){this._realloc(4*e);var i=new Int32Array(this._buffer,this.byteOffset+this.position,e);return DataStream.arrayToNative(i,void 0===t?this.endianness:t),this.position+=4*e,i}mapInt16Array(e,t){this._realloc(2*e);var i=new Int16Array(this._buffer,this.byteOffset+this.position,e);return DataStream.arrayToNative(i,void 0===t?this.endianness:t),this.position+=2*e,i}mapInt8Array(e){this._realloc(e);var t=new Int8Array(this._buffer,this.byteOffset+this.position,e);return this.position+=e,t}mapUint32Array(e,t){this._realloc(4*e);var i=new Uint32Array(this._buffer,this.byteOffset+this.position,e);return DataStream.arrayToNative(i,void 0===t?this.endianness:t),this.position+=4*e,i}mapUint16Array(e,t){this._realloc(2*e);var i=new Uint16Array(this._buffer,this.byteOffset+this.position,e);return DataStream.arrayToNative(i,void 0===t?this.endianness:t),this.position+=2*e,i}mapUint8Array(e){this._realloc(e);var t=new Uint8Array(this._buffer,this.byteOffset+this.position,e);return this.position+=e,t}mapFloat64Array(e,t){this._realloc(8*e);var i=new Float64Array(this._buffer,this.byteOffset+this.position,e);return DataStream.arrayToNative(i,void 0===t?this.endianness:t),this.position+=8*e,i}mapFloat32Array(e,t){this._realloc(4*e);var i=new Float32Array(this._buffer,this.byteOffset+this.position,e);return DataStream.arrayToNative(i,void 0===t?this.endianness:t),this.position+=4*e,i}readInt32Array(e,t){e=void 0===e?this.byteLength-this.position/4:e;var i=new Int32Array(e);return DataStream.memcpy(i.buffer,0,this.buffer,this.byteOffset+this.position,e*i.BYTES_PER_ELEMENT),DataStream.arrayToNative(i,void 0===t?this.endianness:t),this.position+=i.byteLength,i}readInt16Array(e,t){e=void 0===e?this.byteLength-this.position/2:e;var i=new Int16Array(e);return DataStream.memcpy(i.buffer,0,this.buffer,this.byteOffset+this.position,e*i.BYTES_PER_ELEMENT),DataStream.arrayToNative(i,void 0===t?this.endianness:t),this.position+=i.byteLength,i}readInt8Array(e){e=void 0===e?this.byteLength-this.position:e;var t=new Int8Array(e);return DataStream.memcpy(t.buffer,0,this.buffer,this.byteOffset+this.position,e*t.BYTES_PER_ELEMENT),this.position+=t.byteLength,t}readUint32Array(e,t){e=void 0===e?this.byteLength-this.position/4:e;var i=new Uint32Array(e);return DataStream.memcpy(i.buffer,0,this.buffer,this.byteOffset+this.position,e*i.BYTES_PER_ELEMENT),DataStream.arrayToNative(i,void 0===t?this.endianness:t),this.position+=i.byteLength,i}readUint16Array(e,t){e=void 0===e?this.byteLength-this.position/2:e;var i=new Uint16Array(e);return DataStream.memcpy(i.buffer,0,this.buffer,this.byteOffset+this.position,e*i.BYTES_PER_ELEMENT),DataStream.arrayToNative(i,void 0===t?this.endianness:t),this.position+=i.byteLength,i}readUint8Array(e){e=void 0===e?this.byteLength-this.position:e;var t=new Uint8Array(e);return DataStream.memcpy(t.buffer,0,this.buffer,this.byteOffset+this.position,e*t.BYTES_PER_ELEMENT),this.position+=t.byteLength,t}readFloat64Array(e,t){e=void 0===e?this.byteLength-this.position/8:e;var i=new Float64Array(e);return DataStream.memcpy(i.buffer,0,this.buffer,this.byteOffset+this.position,e*i.BYTES_PER_ELEMENT),DataStream.arrayToNative(i,void 0===t?this.endianness:t),this.position+=i.byteLength,i}readFloat32Array(e,t){e=void 0===e?this.byteLength-this.position/4:e;var i=new Float32Array(e);return DataStream.memcpy(i.buffer,0,this.buffer,this.byteOffset+this.position,e*i.BYTES_PER_ELEMENT),DataStream.arrayToNative(i,void 0===t?this.endianness:t),this.position+=i.byteLength,i}writeInt32Array(t,i){if(this._realloc(4*t.length),t instanceof Int32Array&&(this.byteOffset+this.position)%t.BYTES_PER_ELEMENT==0)DataStream.memcpy(this._buffer,this.byteOffset+this.position,t.buffer,t.byteOffset,t.byteLength),this.mapInt32Array(t.length,i);else for(let e=0;e<t.length;e++)this.writeInt32(t[e],i);return this}writeInt16Array(t,i){if(this._realloc(2*t.length),t instanceof Int16Array&&(this.byteOffset+this.position)%t.BYTES_PER_ELEMENT==0)DataStream.memcpy(this._buffer,this.byteOffset+this.position,t.buffer,t.byteOffset,t.byteLength),this.mapInt16Array(t.length,i);else for(let e=0;e<t.length;e++)this.writeInt16(t[e],i);return this}writeInt8Array(t){if(this._realloc(t.length),t instanceof Int8Array&&(this.byteOffset+this.position)%t.BYTES_PER_ELEMENT==0)DataStream.memcpy(this._buffer,this.byteOffset+this.position,t.buffer,t.byteOffset,t.byteLength),this.mapInt8Array(t.length);else for(let e=0;e<t.length;e++)this.writeInt8(t[e]);return this}writeUint32Array(t,i){if(this._realloc(4*t.length),t instanceof Uint32Array&&(this.byteOffset+this.position)%t.BYTES_PER_ELEMENT==0)DataStream.memcpy(this._buffer,this.byteOffset+this.position,t.buffer,t.byteOffset,t.byteLength),this.mapUint32Array(t.length,i);else for(let e=0;e<t.length;e++)this.writeUint32(t[e],i);return this}writeUint16Array(t,i){if(this._realloc(2*t.length),t instanceof Uint16Array&&(this.byteOffset+this.position)%t.BYTES_PER_ELEMENT==0)DataStream.memcpy(this._buffer,this.byteOffset+this.position,t.buffer,t.byteOffset,t.byteLength),this.mapUint16Array(t.length,i);else for(let e=0;e<t.length;e++)this.writeUint16(t[e],i);return this}writeUint8Array(t){if(this._realloc(t.length),t instanceof Uint8Array&&(this.byteOffset+this.position)%t.BYTES_PER_ELEMENT==0)DataStream.memcpy(this._buffer,this.byteOffset+this.position,t.buffer,t.byteOffset,t.byteLength),this.mapUint8Array(t.length);else for(let e=0;e<t.length;e++)this.writeUint8(t[e]);return this}writeFloat64Array(t,i){if(this._realloc(8*t.length),t instanceof Float64Array&&(this.byteOffset+this.position)%t.BYTES_PER_ELEMENT==0)DataStream.memcpy(this._buffer,this.byteOffset+this.position,t.buffer,t.byteOffset,t.byteLength),this.mapFloat64Array(t.length,i);else for(let e=0;e<t.length;e++)this.writeFloat64(t[e],i);return this}writeFloat32Array(t,i){if(this._realloc(4*t.length),t instanceof Float32Array&&(this.byteOffset+this.position)%t.BYTES_PER_ELEMENT==0)DataStream.memcpy(this._buffer,this.byteOffset+this.position,t.buffer,t.byteOffset,t.byteLength),this.mapFloat32Array(t.length,i);else for(let e=0;e<t.length;e++)this.writeFloat32(t[e],i);return this}readInt32(e){e=this._dataView.getInt32(this.position,void 0===e?this.endianness:e);return this.position+=4,e}readInt16(e){e=this._dataView.getInt16(this.position,void 0===e?this.endianness:e);return this.position+=2,e}readInt8(){var e=this._dataView.getInt8(this.position);return this.position+=1,e}readUint32(e){e=this._dataView.getUint32(this.position,void 0===e?this.endianness:e);return this.position+=4,e}readUint16(e){e=this._dataView.getUint16(this.position,void 0===e?this.endianness:e);return this.position+=2,e}readUint8(){var e=this._dataView.getUint8(this.position);return this.position+=1,e}readFloat32(e){e=this._dataView.getFloat32(this.position,void 0===e?this.endianness:e);return this.position+=4,e}readFloat64(e){e=this._dataView.getFloat64(this.position,void 0===e?this.endianness:e);return this.position+=8,e}writeInt32(e,t){return this._realloc(4),this._dataView.setInt32(this.position,e,void 0===t?this.endianness:t),this.position+=4,this}writeInt16(e,t){return this._realloc(2),this._dataView.setInt16(this.position,e,void 0===t?this.endianness:t),this.position+=2,this}writeInt8(e){return this._realloc(1),this._dataView.setInt8(this.position,e),this.position+=1,this}writeUint32(e,t){return this._realloc(4),this._dataView.setUint32(this.position,e,void 0===t?this.endianness:t),this.position+=4,this}writeUint16(e,t){return this._realloc(2),this._dataView.setUint16(this.position,e,void 0===t?this.endianness:t),this.position+=2,this}writeUint8(e){return this._realloc(1),this._dataView.setUint8(this.position,e),this.position+=1,this}writeFloat32(e,t){return this._realloc(4),this._dataView.setFloat32(this.position,e,void 0===t?this.endianness:t),this.position+=4,this}writeFloat64(e,t){return this._realloc(8),this._dataView.setFloat64(this.position,e,void 0===t?this.endianness:t),this.position+=8,this}static memcpy(e,t,i,r,s){const a=new Uint8Array(e,t,s);s=new Uint8Array(i,r,s);a.set(s)}static arrayToNative(e,t){return t===this.endianness?e:this.flipArrayEndianness(e)}static nativeToEndian(e,t){return this.endianness===t?e:this.flipArrayEndianness(e)}static flipArrayEndianness(r){const s=new Uint8Array(r.buffer,r.byteOffset,r.byteLength);for(let i=0;i<r.byteLength;i+=r.BYTES_PER_ELEMENT)for(let e=i+r.BYTES_PER_ELEMENT-1,t=i;e>t;e--,t++){var a=s[t];s[t]=s[e],s[e]=a}return r}static createStringFromArray(t){const i=[];for(let e=0;e<t.length;e+=32768)i.push(String.fromCharCode.apply(void 0,t.subarray(e,e+32768)));return i.join("")}readUCS2String(e,t){return DataStream.createStringFromArray(this.readUint16Array(e,t))}writeUCS2String(e,t,i){void 0===i&&(i=e.length);let r=0;for(;r<e.length&&r<i;r++)this.writeUint16(e.charCodeAt(r),t);for(;r<i;r++)this.writeUint16(0);return this}readString(e,t){return void 0===t||"ASCII"===t?DataStream.createStringFromArray(this.mapUint8Array(void 0===e?this.byteLength-this.position:e)):new TextDecoder(t).decode(this.mapUint8Array(e))}writeString(t,e,i){if(void 0===e||"ASCII"===e)if(void 0!==i){let e;var r=Math.min(t.length,i);for(e=0;e<r;e++)this.writeUint8(t.charCodeAt(e));for(;e<i;e++)this.writeUint8(0)}else for(let e=0;e<t.length;e++)this.writeUint8(t.charCodeAt(e));else this.writeUint8Array((new TextEncoder).encode(t.substring(0,i)));return this}writeUtf8WithLen(e){e=(new TextEncoder).encode(e);return this.writeUint16(e.length).writeUint8Array(e)}readUtf8WithLen(){var e=this.readUint16();return(new TextDecoder).decode(this.mapUint8Array(e))}readCString(e){var t=this.byteLength-this.position,i=new Uint8Array(this._buffer,this._byteOffset+this.position);let r=t;void 0!==e&&(r=Math.min(e,t));let s=0;for(;s<r&&0!==i[s];s++);var a=DataStream.createStringFromArray(this.mapUint8Array(s));return void 0!==e?this.position+=r-s:s!==t&&(this.position+=1),a}writeCString(t,i){if(void 0!==i){let e;var r=Math.min(t.length,i);for(e=0;e<r;e++)this.writeUint8(t.charCodeAt(e));for(;e<i;e++)this.writeUint8(0)}else{for(let e=0;e<t.length;e++)this.writeUint8(t.charCodeAt(e));this.writeUint8(0)}return this}toUint8Array(){return new Uint8Array(this.buffer,this.byteOffset,this.byteLength)}}DataStream.BIG_ENDIAN=!1,DataStream.LITTLE_ENDIAN=!0,DataStream.endianness=0<new Int8Array(new Int16Array([1]).buffer)[0];class IOError extends Error{constructor(){super(...arguments),this.name="IOError"}}class VirtualFile{static async fromRealFile(t){try{const e=new DataStream(await t.arrayBuffer());return e._trimAlloc=()=>{},new this(e,t.name)}catch(e){if(e instanceof DOMException)throw new IOError(`File "${t.name}" could not be read (${e.name})`,{cause:e});throw e}}static fromBytes(e,t){let i=new DataStream(e);return i._trimAlloc=()=>{},new this(i,t)}static factory(e,t,i=0,r=e.byteLength){r=new DataView(e.buffer,e.byteOffset+i,r);const s=new DataStream(r);return s._trimAlloc=()=>{},new this(s,t)}constructor(e,t){this.stream=e,this.filename=t}readAsString(e){return this.stream.seek(0),this.stream.readString(this.stream.byteLength,e)}getBytes(){return new Uint8Array(this.stream.buffer,this.stream.byteOffset,this.stream.byteLength)}getSize(){return this.stream.byteLength}asFile(e){return new File([this.getBytes()],this.filename,{type:e})}}class IniFile{constructor(e){this.sections=new Map,e instanceof VirtualFile?this.fromVirtualFile(e):"object"==typeof e?this.fromJson(e):"string"==typeof e&&this.fromString(e)}fromVirtualFile(e){return this.fromString(e.readAsString())}fromString(e){return this.fromJson((new IniParser).parse(e))}fromJson(e){for(var t in e){var i;e.hasOwnProperty(t)&&(i=new IniSection(t).fromJson(e[t]),this.sections.set(t,i))}return this}toString(){let e=[];for(var t of this.sections.values())e.push(t.toString());return e.join("\r\n")}clone(){let i=new IniFile;return this.sections.forEach((e,t)=>{i.sections.set(t,e.clone())}),i}getOrCreateSection(e){let t=this.sections.get(e);return t||(t=new IniSection(e),this.sections.set(e,t)),t}getSection(e){return this.sections.get(e)}getOrderedSections(){return[...this.sections.values()]}mergeWith(e){return e.sections.forEach((e,t)=>{let i=this.getOrCreateSection(t);i.mergeWith(e)}),this}}class Format3{static decode(r,s,t){let a=new Uint8Array(s*t),n=0,o=0;for(let e=0;e<t;e++){let t=(r[n+1]<<8|r[n])-2;n+=2;let i=0;for(;0<t--;){let e=r[n++];if(0!==e)i++,a[o++]=e;else for(t--,e=r[n++],i+e>s&&(e=s-i&255),i+=e;0!=e--;)a[o++]=0}}return a}}class ShpImage{constructor(e){this.height=1,this.width=1,this.x=0,this.y=0,this.imageData=e??new Uint8Array(0)}clip(i,e){let t=new ShpImage;t.width=Math.min(this.width,i),t.height=Math.min(this.height,e);let r=new Uint8Array(i*e),s=0;for(let t=0;t<this.height&&!(t>=e);t++)for(let e=0;e<this.width;e++)e>=i||(r[s++]=this.imageData[t*this.width+e]);return t.imageData=r,t.x=this.x,t.y=this.y,t}}class ShpFile{constructor(e){this.height=0,this.width=0,this.numImages=0,this.images=[],e instanceof VirtualFile&&this.fromVirtualFile(e)}fromVirtualFile(e){this.filename=e.filename;let s=e.stream;if(0===s.readInt16()){this.width=s.readInt16(),this.height=s.readInt16(),this.numImages=s.readInt16();let r=[];for(let e=0;e<this.numImages;++e)r.push(this.readFrameHeader(s));this.images=[];for(let i=0;i<this.numImages;++i){var{compressionType:a,imageDataStartOffset:n,x:o,y:l,width:h,height:c}=r[i];let e=i<this.numImages-1?r[i+1].imageDataStartOffset:s.byteLength;e<n&&(e=s.byteLength);var u=e-n;s.seek(n);u=this.readImageData(s,h,c,a,u);let t=new ShpImage(u);t.x=o,t.y=l,t.width=h,t.height=c,this.images.push(t)}}}readFrameHeader(e){var t=e.readInt16(),i=e.readInt16(),r=e.readInt16(),s=e.readInt16(),a=e.readUint8();return e.readUint8(),e.readUint8(),e.readUint8(),e.readInt32(),e.readInt32(),{x:t,y:i,width:r,height:s,compressionType:a,imageDataStartOffset:e.readInt32()}}readImageData(r,e,s,t,i){var a=e*s;if(t<=1){var n=new Uint8Array(r.buffer,r.byteOffset+r.position,a);return r.position+=a,n}if(2===t){let t=0,i=new Uint8Array(a);for(let e=0;e<s;++e){var o=r.readUint16()-2;i.set(new Uint8Array(r.buffer,r.byteOffset+r.position,o),t),r.position+=o,t+=o}return i}if(3!==t)return new Uint8Array;t=new Uint8Array(r.buffer,r.byteOffset+r.position,i);return r.position+=i,Format3.decode(t,e,s)}getImage(e){if(e<0||this.images.length<=e)throw new RangeError(`Image index out of bounds (file=${this.filename}, index=${e}, length=${this.images.length})`);return this.images[e]}addImage(e){this.images.push(e),this.numImages++}clip(e,t){let i=new ShpFile;return i.filename=this.filename,i.width=Math.min(this.width,e),i.height=Math.min(this.height,t),i.images=this.images.map(e=>e.clip(i.width,i.height)),i.numImages=this.numImages,i}}var THREE=__webpack_require__(70),Vector3=THREE.Vector3;const normals1=[new Vector3(.54946297,-183e-6,-.835518),new Vector3(.00014400001,.54940403,-.83555698),new Vector3(-.54940403,-68000001e-12,-.83555698),new Vector3(106e-6,-.54946297,-.835518),new Vector3(.94900799,.00031599999,-.31525001),new Vector3(-186e-6,.94899702,-.31528401),new Vector3(-.94899702,.00031800001,-.31528401),new Vector3(-447e-6,-.94900799,-.31525001),new Vector3(.95084399,-279e-6,.30967101),new Vector3(202e-6,.95084798,.30965701),new Vector3(-.95084798,-70000002e-12,.30965701),new Vector3(147e-6,-.95084399,.30967101),new Vector3(.55237001,-11e-6,.83359897),new Vector3(19999999e-12,.55238003,.833592),new Vector3(-.55238003,57000001e-12,.83359301),new Vector3(-66000001e-12,-.55237001,.83359897)],normals2=[new Vector3(.67121398,.19849201,-.714194),new Vector3(.26964301,.58439398,-.76536),new Vector3(-.040546,.096988,-.99445897),new Vector3(-.57242799,-.091913998,-.81478697),new Vector3(-.17140099,-.57270998,-.80163902),new Vector3(.36255699,-.30299899,-.88133103),new Vector3(.81034702,-.34897199,-.470698),new Vector3(.103962,.93867201,-.328767),new Vector3(-.324047,.58766901,-.74137598),new Vector3(-.80086499,.34046099,-.49264699),new Vector3(-.66549802,-.59014702,-.45698899),new Vector3(.314767,-.803002,-.506073),new Vector3(.97262901,.151076,-.17655),new Vector3(.680291,.68423599,-.26272699),new Vector3(-.52007902,.82777703,-.210483),new Vector3(-.96164399,-.179001,-.207847),new Vector3(-.262714,-.937451,-.22840101),new Vector3(.219707,-.97130102,.091124997),new Vector3(.92380798,-.229975,.30608699),new Vector3(-.082488999,.97065997,.225866),new Vector3(-.59179801,.69678998,.40528899),new Vector3(-.92529601,.36660099,.097111002),new Vector3(-.705051,-.68777502,.172828),new Vector3(.7324,-.68036699,-.026304999),new Vector3(.85516202,.37458199,.358311),new Vector3(.47300601,.83648002,.276705),new Vector3(-.097617,.65411198,.750072),new Vector3(-.90412402,-.153725,.39865801),new Vector3(-.211916,-.85808998,.46773201),new Vector3(.50022697,-.67440802,.543091),new Vector3(.584539,-.110249,.80384099),new Vector3(.43737301,.45464399,.77588898),new Vector3(-.042440999,.083318003,.995619),new Vector3(-.59625101,.22013199,.77202803),new Vector3(-.506455,-.39697701,.76544899),new Vector3(.070569001,-.47847399,.87526202)],normals3=[new Vector3(.45651099,-.073968001,-.88663799),new Vector3(.50769401,.38511699,-.77067),new Vector3(.095431998,.22666401,-.96928602),new Vector3(-.35876599,.54318798,-.75910097),new Vector3(-.361276,.13299499,-.92292601),new Vector3(-.48311701,-.32406601,-.813375),new Vector3(-.018073,-.197559,-.980124),new Vector3(.3211,-.501477,-.80337799),new Vector3(.79949099,.069615997,-.59662998),new Vector3(.390971,.77130598,-.50222403),new Vector3(.080782004,.61448997,-.784778),new Vector3(-.73275,.41143101,-.54203498),new Vector3(-.73525399,.0091019999,-.67773098),new Vector3(-.80249399,-.39490801,-.44727099),new Vector3(-.13413,-.58915502,-.79680902),new Vector3(.71955299,-.37622699,-.58369303),new Vector3(.96687502,.173593,-.187132),new Vector3(.760831,.51910597,-.38944301),new Vector3(-.114642,.87551898,-.46938601),new Vector3(-.53236699,.76885903,-.354177),new Vector3(-.96226698,.024977,-.27095801),new Vector3(-.46738699,-.721986,-.51018202),new Vector3(.058449998,-.85235399,-.51968902),new Vector3(.49823299,-.74374002,-.44566301),new Vector3(.93915099,-.27024499,-.212044),new Vector3(.58393198,.80944198,-.061857),new Vector3(.183797,.97322798,-.138007),new Vector3(-.88435501,.45221901,-.115822),new Vector3(-.943178,-.33206701,.012138),new Vector3(-.69844002,-.70656699,-.113772),new Vector3(-.228411,-.95470601,-.190694),new Vector3(.73156399,-.675861,-.089588001),new Vector3(.96925098,.046804,.24158201),new Vector3(.85564703,.50347698,.119916),new Vector3(-.25115299,.96794701,-80999998e-12),new Vector3(-.64779502,.75674897,.087711997),new Vector3(-.96916401,.14519399,.1991),new Vector3(-.41479301,-.88896698,.194126),new Vector3(.25077501,-.961178,-.115109),new Vector3(.47862899,-.84259301,.246883),new Vector3(.89004397,-.39614201,.225595),new Vector3(.52405101,.76235998,.37970701),new Vector3(.11962,.94548202,.30291),new Vector3(-.76085001,.49007499,.42536199),new Vector3(-.86978501,-.20215,.450122),new Vector3(-.70946699,-.60242403,.36570701),new Vector3(.019308999,-.95887101,.28318599),new Vector3(.626113,-.564677,.53770101),new Vector3(.769943,-.126663,.62541503),new Vector3(.76419097,.35070199,.54131401),new Vector3(-.001878,.74136698,.67109799),new Vector3(-.37088001,.81836802,.43900099),new Vector3(-.71390897,.12865201,.68831801),new Vector3(-.295165,-.73866397,.60601401),new Vector3(.186195,-.73836899,.648184),new Vector3(.387523,-.35878301,.84917599),new Vector3(.481022,.124846,.86777401),new Vector3(.391808,.54505599,.741216),new Vector3(-.0035359999,.36559799,.93076599),new Vector3(-.42049801,.484961,.76680797),new Vector3(-.35490301,.019470001,.93470001),new Vector3(-.54783702,-.35920799,.75554299),new Vector3(-.106662,-.445115,.88909799),new Vector3(.086796001,-.059307002,.99445897)],normals4=[new Vector3(.52657801,-.35962099,-.77031702),new Vector3(.150482,.43598399,.88728398),new Vector3(.414195,.73825502,-.53237402),new Vector3(.075152002,.91624898,-.393498),new Vector3(-.316149,.93073601,-.18379299),new Vector3(-.77381903,.62333399,-.11251),new Vector3(-.90084201,.42853701,-.069568001),new Vector3(-.99894202,-.010971,.044665001),new Vector3(-.979761,-.15767001,-.123324),new Vector3(-.91127402,-.362371,-.19562),new Vector3(-.62406898,-.72094101,-.301301),new Vector3(-.310173,-.80934501,-.498752),new Vector3(.146613,-.81581903,-.55941403),new Vector3(-.71651602,-.69435602,-.066887997),new Vector3(.50397199,-.114202,-.85613698),new Vector3(.45549101,.87262702,-.176211),new Vector3(-.00501,-.114373,-.99342501),new Vector3(-.104675,-.327701,-.93896502),new Vector3(.56041199,.75258899,-.34575599),new Vector3(-.060575999,.82162797,-.566796),new Vector3(-.30234101,.79700702,-.522847),new Vector3(-.671543,.67074001,-.314863),new Vector3(-.77840102,-.12835699,.61450499),new Vector3(-.92404997,.278382,-.261985),new Vector3(-.69977301,-.55049098,-.45527801),new Vector3(-.56824797,-.51718903,-.64000797),new Vector3(.054097999,-.93286401,-.356143),new Vector3(.75838202,.57289302,-.31088799),new Vector3(.0036200001,.30502599,-.95233703),new Vector3(-.060849998,-.98688602,-.14951099),new Vector3(.63523,.045478001,-.77098298),new Vector3(.52170497,.241309,-.81828701),new Vector3(.26940399,.63542497,-.72364098),new Vector3(.045676,.67275399,-.738455),new Vector3(-.180511,.67465699,-.71571898),new Vector3(-.397131,.63664001,-.66104198),new Vector3(-.55200398,.47251499,-.687038),new Vector3(-.77217001,.08309,-.62996),new Vector3(-.669819,-.119533,-.73284),new Vector3(-.54045498,-.31844401,-.77878201),new Vector3(-.38613501,-.522789,-.75999397),new Vector3(-.261466,-.68856698,-.676395),new Vector3(-.019412,-.69610298,-.71767998),new Vector3(.30356899,-.48184401,-.82199299),new Vector3(.68193901,-.19512901,-.70490003),new Vector3(-.24488901,-.116562,-.96251899),new Vector3(.80075902,-.022979001,-.59854603),new Vector3(-.37027499,.095583998,-.92399102),new Vector3(-.33067101,-.32657799,-.88543999),new Vector3(-.16322,-.52757901,-.83367902),new Vector3(.12639,-.313146,-.941257),new Vector3(.34954801,-.27222601,-.89649802),new Vector3(.23991799,-.085825004,-.96699202),new Vector3(.390845,.081537001,-.91683799),new Vector3(.25526699,.26869699,-.92878503),new Vector3(.146245,.48043799,-.86474901),new Vector3(-.32601601,.47845599,-.81534898),new Vector3(-.46968201,-.112519,-.87563598),new Vector3(.81844002,-.25852001,-.51315099),new Vector3(-.474318,.292238,-.83043301),new Vector3(.778943,.39584199,-.48637101),new Vector3(.62409401,.39377299,-.67487001),new Vector3(.74088597,.203834,-.63995302),new Vector3(.48021701,.565768,-.67029703),new Vector3(.38093001,.42453501,-.82137799),new Vector3(-.093422003,.50112402,-.86031801),new Vector3(-.236485,.29619801,-.92538702),new Vector3(-.131531,.093959004,-.98684901),new Vector3(-.82356203,.29577699,-.48400599),new Vector3(.61106598,-.624304,-.486664),new Vector3(.069495998,-.52033001,-.85113299),new Vector3(.226522,-.66487902,-.711775),new Vector3(.47130799,-.56890398,-.67395699),new Vector3(.38842499,-.74262398,-.54556),new Vector3(.78367501,-.48072901,-.39338499),new Vector3(.962394,.135676,-.235349),new Vector3(.876607,.172034,-.449406),new Vector3(.63340503,.58979303,-.50094098),new Vector3(.182276,.80065799,-.57072097),new Vector3(.177003,.76413399,.62029701),new Vector3(-.544016,.675515,-.49772099),new Vector3(-.67929697,.28646699,-.67564201),new Vector3(-.59039098,.091369003,-.801929),new Vector3(-.82436001,-.13312399,-.55018902),new Vector3(-.71579403,-.33454201,-.61296099),new Vector3(.17428599,-.89248401,.416049),new Vector3(-.082528003,-.83712298,-.54075301),new Vector3(.28333101,-.88087398,-.37918901),new Vector3(.675134,-.42662701,-.60181701),new Vector3(.84372002,-.512335,-.160156),new Vector3(.97730398,-.098555997,-.18752),new Vector3(.846295,.522672,-.102947),new Vector3(.67714101,.72132498,-.145501),new Vector3(.32096499,.87089199,-.37219399),new Vector3(-.178978,.911533,-.37023601),new Vector3(-.44716901,.82670099,-.341474),new Vector3(-.70320302,.496328,-.50908101),new Vector3(-.97718102,.063562997,-.202674),new Vector3(-.87817001,-.412938,.241455),new Vector3(-.83583099,-.35855001,-.415728),new Vector3(-.499174,-.69343299,-.51959199),new Vector3(-.188789,-.92375302,-.33322501),new Vector3(.19225401,-.96936101,-.152896),new Vector3(.51594001,-.783907,-.34539199),new Vector3(.90592498,-.30095199,-.29787099),new Vector3(.99111199,-.127746,.037106998),new Vector3(.99513501,.098424003,-.0043830001),new Vector3(.76012301,.64627701,.067367002),new Vector3(.205221,.95958,-.192591),new Vector3(-.042750001,.97951299,-.19679099),new Vector3(-.43801701,.89892697,.0084920004),new Vector3(-.82199401,.48078501,-.30523899),new Vector3(-.89991701,.081710003,-.42833701),new Vector3(-.92661202,-.144618,-.347096),new Vector3(-.79365999,-.55779201,-.24283899),new Vector3(-.43134999,-.84777898,-.30855799),new Vector3(-.0054919999,-.96499997,.26219299),new Vector3(.58790499,-.80402601,-.088940002),new Vector3(.69949299,-.66768599,-.254765),new Vector3(.88930303,.359795,-.282291),new Vector3(.780972,.197037,.59267199),new Vector3(.52012098,.50669599,.68755698),new Vector3(.40389499,.69396102,.59605998),new Vector3(-.154983,.89923602,.40909001),new Vector3(-.65733802,.53716803,.528543),new Vector3(-.74619502,.33409101,.575827),new Vector3(-.62495202,-.049144,.77911502),new Vector3(.31814101,-.254715,.913185),new Vector3(-.555897,.405294,.725752),new Vector3(-.79443401,.099405997,.59916002),new Vector3(-.64036101,-.68946302,.33849499),new Vector3(-.12671299,-.73409498,.66711998),new Vector3(.105457,-.78081697,.61579502),new Vector3(.40799299,-.48091599,.77605498),new Vector3(.69513601,-.54512,.468647),new Vector3(.97319102,-.0064889998,.229908),new Vector3(.94689399,.317509,-.050799001),new Vector3(.56358302,.82561201,.027183),new Vector3(.325773,.94542301,.0069490001),new Vector3(-.171821,.98509699,-.0078149997),new Vector3(-.67044097,.73993897,.054768998),new Vector3(-.822981,.55496198,.121322),new Vector3(-.96619302,.117857,.229307),new Vector3(-.95376903,-.29470399,.058945),new Vector3(-.86438698,-.50272799,-.010015),new Vector3(-.53060901,-.84200603,-.097365998),new Vector3(-.162618,-.98407501,.071772002),new Vector3(.081446998,-.99601102,.036439002),new Vector3(.74598402,-.66596299,.00076199998),new Vector3(.94205701,-.32926899,-.064106002),new Vector3(.93970197,-.28108999,.194803),new Vector3(.77121401,.55067003,.319363),new Vector3(.641348,.73069,.23402099),new Vector3(.080682002,.99669099,.0098789996),new Vector3(-.046725001,.97664303,.20972501),new Vector3(-.53107601,.82100099,.209562),new Vector3(-.69581503,.65599,.29243499),new Vector3(-.97612202,.216709,-.014913),new Vector3(-.96166098,-.14412899,.23331399),new Vector3(-.772084,-.61364698,.165299),new Vector3(-.44960001,-.83605999,.314426),new Vector3(-.39269999,-.91461599,.096247002),new Vector3(.390589,-.91947001,.044890001),new Vector3(.58252901,-.79919797,.148127),new Vector3(.866431,-.48981199,.096864),new Vector3(.90458697,.111498,.41145),new Vector3(.95353699,.23232999,.191806),new Vector3(.497311,.77080297,.398177),new Vector3(.194066,.95631999,.218611),new Vector3(.422876,.882276,.206797),new Vector3(-.373797,.84956598,.37217399),new Vector3(-.53449702,.71402299,.4522),new Vector3(-.881827,.23716,.40759799),new Vector3(-.904948,-.014069,.42528901),new Vector3(-.751827,-.51281703,.41445801),new Vector3(-.50101501,-.69791698,.51175803),new Vector3(-.23519,-.92592299,.295555),new Vector3(.228983,-.95393997,.193819),new Vector3(.734025,-.63489801,.241062),new Vector3(.91375297,-.063253,-.40131599),new Vector3(.90573502,-.161487,.391875),new Vector3(.85892999,.342446,.38074899),new Vector3(.62448603,.60758102,.49077699),new Vector3(.28926399,.85747898,.42550799),new Vector3(.069968,.90216899,.42567101),new Vector3(-.28617999,.94069999,.182165),new Vector3(-.57401299,.80511898,-.14930899),new Vector3(.111258,.099717997,-.98877603),new Vector3(-.30539301,-.94422799,-.12316),new Vector3(-.60116601,-.78957599,.123163),new Vector3(-.290645,-.81213999,.50591898),new Vector3(-.064920001,-.87716299,.47578499),new Vector3(.408301,-.862216,.29978901),new Vector3(.56609702,-.72556603,.39126399),new Vector3(.83936399,-.427387,.33586901),new Vector3(.81889999,-.041305002,.57244802),new Vector3(.71978402,.41499701,.55649698),new Vector3(.88174403,.45027,.140659),new Vector3(.40182301,-.89822,-.17815199),new Vector3(-.054019999,.79134399,.60898),new Vector3(-.29377401,.76399398,.57446498),new Vector3(-.450798,.61034697,.65135098),new Vector3(-.63822103,.186694,.74687302),new Vector3(-.87287003,-.25712699,.41470799),new Vector3(-.58725703,-.52170998,.618828),new Vector3(-.35365799,-.64197397,.680291),new Vector3(.041648999,-.61127299,.79032302),new Vector3(.348342,-.77918297,.52108699),new Vector3(.499167,-.62244099,.602826),new Vector3(.79001898,-.30383101,.53250003),new Vector3(.66011798,.060733002,.74870199),new Vector3(.60492098,.29416099,.73996001),new Vector3(.38569701,.37934601,.84103203),new Vector3(.239693,.207876,.94833201),new Vector3(.012623,.25853199,.96591997),new Vector3(-.100557,.457147,.88368797),new Vector3(.046967,.62858802,.77631903),new Vector3(-.43039101,-.44540501,.785097),new Vector3(-.43429101,-.196228,.87913901),new Vector3(-.25663701,-.336867,.90590203),new Vector3(-.131372,-.15891001,.97851402),new Vector3(.102379,-.208767,.972592),new Vector3(.195687,-.450129,.87125802),new Vector3(.62731898,-.42314801,.65377098),new Vector3(.68743902,-.171583,.70568198),new Vector3(.27592,-.021255,.96094602),new Vector3(.45936701,.15746599,.87417799),new Vector3(.285395,.583184,.76055598),new Vector3(-.81217402,.46030301,.35846099),new Vector3(-.189068,.64122301,.743698),new Vector3(-.338875,.47648001,.811252),new Vector3(-.92099398,.347186,.176727),new Vector3(.040638998,.024465,.99887401),new Vector3(-.73913199,-.35374701,.57318997),new Vector3(-.60351199,-.28661501,.74405998),new Vector3(-.188676,-.547059,.81555402),new Vector3(-.026045,-.39782,.91709399),new Vector3(.26789701,-.649041,.71202302),new Vector3(.518246,-.28489101,.80638599),new Vector3(.493451,-.066532999,.86722499),new Vector3(-.328188,.140251,.93414301),new Vector3(.328188,.140251,.93414301),new Vector3(-.328188,.140251,.93414301),new Vector3(-.328188,.140251,.93414301),new Vector3(-.328188,.140251,.93414301)];class VoxelField{constructor(e,t,i){this.sizeX=e,this.sizeY=t,this.sizeZ=i,this.arr=new Array(e*t*i)}add(e){this.arr[e.x+e.y*this.sizeX+e.z*this.sizeX*this.sizeY]=e}get(e,t,i){if(!(e>=this.sizeX||t>=this.sizeY||i>=this.sizeZ))return this.arr[e+t*this.sizeX+i*this.sizeX*this.sizeY]}}var Section_THREE=__webpack_require__(70);class Section{get spanX(){return this.maxBounds.x-this.minBounds.x}get spanY(){return this.maxBounds.y-this.minBounds.y}get spanZ(){return this.maxBounds.z-this.minBounds.z}get scaleX(){return this.spanX/this.sizeX}get scaleY(){return this.spanY/this.sizeY}get scaleZ(){return this.spanZ/this.sizeZ}get scale(){return new Section_THREE.Vector3(this.scaleX,this.scaleY,this.scaleZ)}getAllVoxels(){let i=[],r=new VoxelField(this.sizeX+1,this.sizeY+1,this.sizeZ+1);for(let e=0,t=this.spans.length;e<t;e++){var s=this.spans[e].voxels;for(let e=0,t=s.length;e<t;e++){var a=s[e];i.push(a),r.add(a)}}return{voxels:i,voxelField:r}}getNormals(){switch(this.normalsMode){case 1:return normals1;case 2:return normals2;case 3:return normals3;case 4:return normals4;default:throw new Error("Invalid normalsmode "+this.normalsMode)}}scaleHvaMatrix(e){return(e=e.clone()).elements[12]*=this.hvaMultiplier,e.elements[13]*=this.hvaMultiplier,e.elements[14]*=this.hvaMultiplier,e}toPlain(){return{name:this.name,normalsMode:this.normalsMode,minBounds:this.minBounds.toArray(),maxBounds:this.maxBounds.toArray(),sizeX:this.sizeX,sizeY:this.sizeY,sizeZ:this.sizeZ,hvaMultiplier:this.hvaMultiplier,transfMatrix:this.transfMatrix.toArray(),spans:this.spans}}fromPlain(e){return this.name=e.name,this.normalsMode=e.normalsMode,this.minBounds=(new Section_THREE.Vector3).fromArray(e.minBounds),this.maxBounds=(new Section_THREE.Vector3).fromArray(e.maxBounds),this.sizeX=e.sizeX,this.sizeY=e.sizeY,this.sizeZ=e.sizeZ,this.hvaMultiplier=e.hvaMultiplier,this.transfMatrix=(new Section_THREE.Matrix4).fromArray(e.transfMatrix),this.spans=e.spans,this}}class VxlHeader{read(e){this.fileName=e.readCString(16),this.paletteCount=e.readUint32(),this.headerCount=e.readUint32(),this.tailerCount=e.readUint32(),this.bodySize=e.readUint32(),this.paletteRemapStart=e.readUint8(),this.paletteRemapEnd=e.readUint8(),e.seek(e.position+768)}}VxlHeader.size=32;var VxlFile_THREE=__webpack_require__(70);class VxlFile{constructor(e){this.voxelCount=0,e instanceof VirtualFile&&this.fromVirtualFile(e)}fromVirtualFile(e){this.filename=e.filename;let s=e.stream;if(this.sections=[],!(s.byteLength<VxlHeader.size)){let r=new VxlHeader;if(r.read(s),r.headerCount&&r.tailerCount&&r.tailerCount===r.headerCount){for(let e=0;e<r.headerCount;++e){const n=new Section;this.readSectionHeader(n,s),this.sections.find(e=>e.name===n.name)&&console.warn(`Duplicate section name "${n.name}" found in VXL "${this.filename}".`),this.sections.push(n)}var a=s.position;s.seek(s.position+r.bodySize);let t=[];for(let e=0;e<r.tailerCount;++e)t[e]=this.readSectionTailer(this.sections[e],s);let i=0;for(let e=0;e<r.headerCount;++e)s.seek(a),i+=this.readSectionBodySpans(this.sections[e],t[e],s);this.voxelCount=i}}}readSectionHeader(e,t){e.name=t.readCString(16),t.readUint32(),t.readUint32(),t.readUint32()}readSectionTailer(e,t){var i=t.readUint32(),r=t.readUint32(),s=t.readUint32();return e.hvaMultiplier=t.readFloat32(),e.transfMatrix=this.readTransfMatrix(t),e.minBounds=new VxlFile_THREE.Vector3(t.readFloat32(),t.readFloat32(),t.readFloat32()),e.maxBounds=new VxlFile_THREE.Vector3(t.readFloat32(),t.readFloat32(),t.readFloat32()),e.sizeX=t.readUint8(),e.sizeY=t.readUint8(),e.sizeZ=t.readUint8(),e.normalsMode=t.readUint8(),{startingSpanOffset:i,endingSpanOffset:r,dataSpanOffset:s}}readTransfMatrix(t){let i=[];for(let e=0;e<3;++e)i.push(t.readFloat32(),t.readFloat32(),t.readFloat32(),t.readFloat32());return i.push(0,0,0,1),(new VxlFile_THREE.Matrix4).fromArray(i).transpose()}readSectionBodySpans(e,t,i){i.seek(i.position+t.startingSpanOffset);var{sizeX:r,sizeY:s,sizeZ:a}=e;let n=new Array(s);for(let t=0;t<s;++t){n[t]=new Array(r);for(let e=0;e<r;++e)n[t][e]=i.readInt32()}let o=new Array(s);for(let t=0;t<s;++t){o[t]=new Array(r);for(let e=0;e<r;++e)o[t][e]=i.readInt32()}let l=e.spans=[],h=0;for(let t=0;t<s;++t)for(let e=0;e<r;++e){var c={x:e,y:t,voxels:this.readSpanVoxels(n[t][e],o[t][e],e,t,a,i)};l.push(c),h+=c.voxels.length}return h}readSpanVoxels(e,t,i,r,s,a){if(-1===e||-1===t)return[];let n=[];for(let t=0;t<s;){t+=a.readUint8();var o=a.readUint8();for(let e=0;e<o;++e){var l={x:i,y:r,z:t++,colorIndex:a.readUint8(),normalIndex:a.readUint8()};n.push(l)}a.readUint8()}return n}fromPlain(e){return this.sections=e.sections.map(e=>(new Section).fromPlain(e)),this.voxelCount=e.voxelCount,this}toPlain(){return{sections:this.sections.map(e=>e.toPlain()),voxelCount:this.voxelCount}}getSection(e){return this.sections[e]}}var DataPrecencyFlags,TmpImage_THREE=__webpack_require__(70);!function(e){e[e.ExtraData=1]="ExtraData",e[e.ZData=2]="ZData",e[e.DamagedData=4]="DamagedData"}(DataPrecencyFlags=DataPrecencyFlags||{});const unsignInt8=e=>e<0?e+256:e;class TmpImage{constructor(e,t,i){this.fromStream(e,t,i)}fromStream(e,t,i){this.x=e.readInt32(),this.y=e.readInt32(),e.readInt32(),e.readInt32();var r=e.readInt32();this.extraX=e.readInt32(),this.extraY=e.readInt32(),this.extraWidth=e.readInt32(),this.extraHeight=e.readInt32();var s=e.readUint32();this.height=e.readUint8(),this.terrainType=e.readUint8(),this.rampType=e.readUint8(),this.radarLeft=this.readRadarRgb(e.readInt8(),e.readInt8(),e.readInt8()),this.radarRight=this.readRadarRgb(e.readInt8(),e.readInt8(),e.readInt8()),e.seek(e.position+3),this.tileData=new Uint8Array(e.buffer,e.byteOffset+e.position,t*i/2),e.position+=t*i/2,this.hasZData=(s&DataPrecencyFlags.ZData)===DataPrecencyFlags.ZData,this.hasZData&&(e.position+=t*i/2),this.hasExtraData=(s&DataPrecencyFlags.ExtraData)===DataPrecencyFlags.ExtraData,this.hasExtraData&&(s=Math.abs(this.extraWidth*this.extraHeight),this.extraData=new Uint8Array(e.buffer,e.byteOffset+e.position,s),e.position+=s),this.hasZData&&this.hasExtraData&&0<r&&r<e.byteLength&&(e.position+=Math.abs(this.extraWidth*this.extraHeight))}readRadarRgb(e,t,i){return new TmpImage_THREE.Color(unsignInt8(e)/255,unsignInt8(t)/255,unsignInt8(i)/255)}}class TmpFile{constructor(e){this.images=[],e instanceof VirtualFile&&this.fromVirtualFile(e)}fromVirtualFile(e){let t=e.stream;this.width=t.readInt32(),this.height=t.readInt32(),this.blockWidth=t.readInt32(),this.blockHeight=t.readInt32();var i=this.width*this.height,r=new Uint8Array(t.buffer,t.byteOffset+t.position,4*i);this.images=[];for(let e=0;e<i;e++){var s=r[4*e+3]<<24|r[4*e+2]<<16|r[4*e+1]<<8|r[4*e];t.seek(s);s=new TmpImage(t,this.blockWidth,this.blockHeight);this.images.push(s)}}}class Base64{static encode(e){return void 0!==globalThis.btoa?globalThis.btoa(e):Buffer.from(e,"binary").toString("base64")}static decode(e){return void 0!==globalThis.atob?globalThis.atob(e):Buffer.from(e,"base64").toString("binary")}static isBase64(e){return!!e.match(/^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$/)}}function pad(e,t="0000"){e=""+e;return t.substring(0,t.length-e.length)+e}function equalsIgnoreCase(e,t){return e.toLowerCase()===t.toLowerCase()}function binaryStringToUint8Array(t){var i=t.length;let r=new Uint8Array(i);for(let e=0;e<i;e++)r[e]=t.charCodeAt(e);return r}function base64StringToUint8Array(e){return binaryStringToUint8Array(Base64.decode(e))}function uint8ArrayToBase64String(e){return Base64.encode(uint8ArrayToBinaryString(e))}function uint8ArrayToBinaryString(e){return e.reduce((e,t)=>e+String.fromCharCode(t),"")}function utf16ToBinaryString(t){var i=t.length;let r="";for(let e=0;e<i;e++){var s=t.charCodeAt(e);r+=String.fromCharCode(s>>8),r+=String.fromCharCode(255&s)}return r}function binaryStringToUtf16(t){var i=t.length;let r="";for(let e=0;e<i;e+=2){var s=(t.charCodeAt(e)<<8)+t.charCodeAt(e+1);r+=String.fromCharCode(s)}return r}function bufferToHexString(e){const t=[],i=new DataView(e);for(let e=0;e<i.byteLength;e+=4){const s=i.getUint32(e);var r="00000000",r=(r+s.toString(16)).slice(-r.length);t.push(r)}return t.join("")}class Color{static fromRgb(e,t,i){return new Color(e,t,i)}static fromHsv(e,t,i){let r=0,s=0,a=0;if(e=e/255*360%360,i/=255,0===(t/=255))r=i,s=i,a=i;else{var n=e/60,e=Math.floor(n),n=n-e,o=i*(1-t),l=i*(1-t*n),h=i*(1-t*(1-n));switch(e){case 0:r=i,s=h,a=o;break;case 1:r=l,s=i,a=o;break;case 2:r=o,s=i,a=h;break;case 3:r=o,s=l,a=i;break;case 4:r=h,s=o,a=i;break;case 5:r=i,s=o,a=l}}return Color.fromRgb(Math.floor(255*r),Math.floor(255*s),Math.floor(255*a))}constructor(e,t,i){this.r=e,this.g=t,this.b=i}asHex(){return(this.r<<16)+(this.g<<8)+this.b}asHexString(){return"#"+pad(this.asHex().toString(16),"000000")}clone(){return new Color(this.r,this.g,this.b)}}function getRandomInt(e,t){return Math.floor(Math.random()*(t+1-e))+e}function clamp(e,t,i){return Math.min(i,Math.max(e,t))}function isBetween(e,t,i){return t<=e&&e<=i}function lerp(e,t,i){return(1-i)*e+i*t}function truncToDecimals(e,t){if(!e)return e;t=10**t;return 0<=e?Math.floor(e*t)/t:Math.ceil(e*t)/t}function roundToDecimals(e,t){if(!e)return e;t=10**t;return Math.round(e*t)/t}function floorTo(e,t){return Math.floor(e/t)*t}function fnv32a(i){let r=2166136261;for(let e=0,t=i.length;e<t;++e)r^=i[e],r+=(r<<1)+(r<<4)+(r<<7)+(r<<8)+(r<<24);return r>>>0}class Palette{constructor(e){e instanceof VirtualFile?this.fromVirtualFile(e):"object"==typeof e&&this.fromJson(e)}fromVirtualFile(e){e=e.stream.readUint8Array(768);this.fromJson(e)}fromJson(t){this.colors=[];for(let e=0;e<t.length/3;++e)this.colors.push(Color.fromRgb(4*t[3*e],4*t[3*e+1],4*t[3*e+2]));this._hash=this.computeHash(this.colors)}getColor(e){return this.colors[e]}getColorAsHex(e){return this.getColor(e).asHex()}setColors(e){this.colors=e,this._hash=this.computeHash(this.colors)}get size(){return this.colors.length}get hash(){return this._hash}computeHash(e){let t=new Uint8Array(3*this.size),i=0;for(var r of e)t[i]=r.r,t[i+1]=r.g,t[i+2]=r.b,i+=3;return fnv32a(t)}clone(){let e=new Palette;return e.colors=this.colors.map(e=>e.clone()),e._hash=this._hash,e}remap(t){var i=[63,59,55,52,48,44,41,37,33,30,26,22,19,15,11,8];for(let e=Palette.REMAP_START_IDX;e<Palette.REMAP_START_IDX+i.length;e++)this.colors[e].r=Math.floor(t.r/255*i[e-Palette.REMAP_START_IDX]*4),this.colors[e].g=Math.floor(t.g/255*i[e-Palette.REMAP_START_IDX]*4),this.colors[e].b=Math.floor(t.b/255*i[e-Palette.REMAP_START_IDX]*4);return this._hash=this.computeHash(this.colors),this}}Palette.REMAP_START_IDX=16;class GameMath{static reverseSinTableLookup(e,t,i,r){for(;t<=i;){var s=Math.floor((t+i)/2),a=this.SIN_TABLE[s];if(a===e)return s;(r?e<a:a<e)?t=s+1:i=s-1}return Math.abs(e-this.SIN_TABLE[t])<Math.abs(e-this.SIN_TABLE[i])?t:i}static pow(e,t){if(!Number.isFinite(e)||!Number.isFinite(t)||Number.isSafeInteger(e)&&Number.isSafeInteger(t))return e**t;if(!Number.isSafeInteger(t))throw new Error("Exponent must be a safe integer");return Math.floor(e*this.EXP_10_PRECISION)**t/this.EXP_10_PRECISION**t}static sqrt(e){if(0===e)return 0;var t;let i=e/3;for(;t=i,i=(e/i+i)/2,5e-15<Math.abs(t-i););return i}static sin(e){if(!Number.isFinite(e))return NaN;if(!e)return e;e=e/(2*Math.PI)-Math.floor(e/(2*Math.PI)),e=Math.floor(e*this.SIN_TABLE.length);return this.SIN_TABLE[e]}static cos(e){return this.sin(e+Math.PI/2)}static asin(e){if(!isBetween(e,-1,1))return NaN;if(!e)return 0;let t;var i=this.SIN_TABLE.length;return t=0<e?2*Math.PI*this.reverseSinTableLookup(e,0,i/4,!1)/i:Math.PI-2*Math.PI*this.reverseSinTableLookup(e,i/2,.75*i,!0)/i,t}static acos(e){return Math.PI/2-this.asin(e)}static atan2(e,t){if(Number.isNaN(t)||Number.isNaN(e))return NaN;let i;return i=Number.isFinite(e)||Number.isFinite(t)?Number.isFinite(t)&&0!==e?Number.isFinite(e)&&0!==t?this.atan2FiniteNonZero(e,t):this.signIncZero(e)*Math.PI*.5:this.signIncZero(e)*(this.signIncZero(t)<0?Math.PI:0):Math.sign(e)*Math.PI*(0<Math.sign(t)?.25:.75),i}static atan2FiniteNonZero(e,t){var i=Math.abs(t),r=Math.abs(e),s=Math.min(i,r)/Math.max(i,r),a=s*s;let n=((-.0464964749*a+.15931422)*a-.327622764)*a*s+s;return i<r&&(n=Math.PI/2-n),t<0&&(n=Math.PI-n),e<0&&(n=-n),n}static signIncZero(e){return e===-1/0||1/e<0?-1:1}}GameMath.PRECISION=6,GameMath.EXP_10_PRECISION=10**GameMath.PRECISION,GameMath.SIN_TABLE=[0,.004848117819001859,.009696121685978396,.014543897651582654,.01939133177182437,.024238310110748135,.0290847187431114,.03393044375706223,.03877537125681671,.043619387365336,.04846237822700296,.05330423001029823,.05814482891047582,.06298406115223795,.06782181299240934,.0726579707226106,.07749242067193093,.08232504920959989,.08715574274765817,.09198438774362744,.09681087070317909,.10163507818280187,.10645689679246824,.11127621319829964,.11609291412523022,.12090688635966935,.12571801675216268,.13052619222005157,.13533129975013108,.14013322640130627,.14493185930724672,.1497270856790396,.15451879280784048,.15930686806752256,.16409119891732396,.1688716729044928,.17364817766693033,.17842060093583212,.18318883053832663,.18795275440011186,.19271226054808968,.19746723711299752,.20221757233203794,.20696315455150538,.2117038722294107,.21643961393810288,.22117026836688775,.2258957243246448,.23061587074244014,.2353305966761376,.24003979130900588,.2447433439543238,.24944114405798126,.25413308120107847,.25881904510252074,.26349892562161076,.2681726127606373,.272839996667461,.27750096763809573,.28215541611928774,.2868032327110902,.29144430816943495,.2960785334086999,.3007057995042731,.3053259976951131,.30993901938630514,.31454475615161365,.31914309973603083,.323733942058321,.328317175213561,.33289269147567657,.3374603832999741,.3420201433256687,.34657186437840753,.3511154394727888,.3556507618148765,.3601777248047104,.36469622203881186,.3692061473126844,.3737073946233105,.3781998581716425,.3826834323650898,.3871580118200006,.3916234913641391,.3960797660391568,.4005267311030606,.4049642820326736,.4093923145260926,.4138107245051391,.4182194081178064,.42261826174069944,.4270071819814715,.4313860656812534,.4357548099170794,.4401133120043048,.44446146949902104,.4487991802004621,.4531263421534082,.4574428536505808,.4617486132350339,.46604351970253877,.4703274721039625,.4746003697476404,.4788621122017435,.4831125992966384,.48735173112724234,.49157940805537054,.49579553071207916,.49999999999999994,.5041927170956704,.5083735834518556,.5125425007998652,.5166993711518628,.5208440968031697,.5249765803345602,.5290967246145525,.5332044328016912,.5372996083468239,.5413821549953696,.5454519767895825,.549508978070806,.5535530634817223,.5575841379685927,.5616021067834929,.5656068754865385,.5695983499481065,.573576436351046,.5775410411928851,.5814920712880266,.5854294337699405,.5893530360933448,.593262786036382,.5971585917027862,.6010403615240428,.6049080042615417,.6087614290087207,.6126005451932028,.6164252625789254,.62023549126826,.6240311417041269,.6278121246720986,.6315783513024975,.6353297330724851,.6390661818081416,.6427876096865393,.6464939292378065,.6501850533471834,.6538608952570697,.6575213685690636,.6611663872459932,.6647958656139378,.6684097183642425,.6720078605555224,.6755902076156601,.6791566753437932,.6827071799122926,.6862416378687335,.6897599661378576,.6932620820235242,.696747903210655,.7002173477671685,.7036703341459059,.7071067811865475,.710526608117521,.713929734557899,.7173160805192894,.7206855664077146,.7240381130254825,.7273736415730487,.7306920736508674,.7339933312612352,.7372773368101241,.7405440131090046,.7437932833766612,.747025071240996,.7502393007408245,.7534358963276606,.7566147828674927,.7597758856425494,.7629191303530553,.766044443118978,.7691517504817651,.7722409794060692,.7753120572814658,.7783649119241599,.7813994715786823,.7844156649195757,.7874134210530723,.7903926695187593,.7933533402912352,.7962953637817558,.7992186708398696,.8021231927550437,.8050088612582783,.8078756085237111,.8107233671702122,.8135520702629676,.8163616513150519,.8191520442889918,.821923183598318,.8246750041091067,.8274074411415104,.8301204304712788,.8328139083312671,.8354878114129364,.8381420768678404,.8407766423091032,.8433914458128856,.845986425919841,.848561521636559,.8511166724369997,.8536518182639162,.8561668995302665,.8586618571206132,.8611366323925137,.8635911671778986,.8660254037844386,.8684392849969005,.870832754078492,.8732057547721958,.8755582313020908,.8778901283746645,.8802013911801111,.8824919653936212,.8847617971766577,.8870108331782216,.8892390205361062,.8914463068781385,.8936326403234122,.8957979694835052,.8979422434636881,.9000654118641211,.9021674247810376,.9042482328079179,.9063077870366499,.9083460390586793,.9103629409661466,.9123584453530141,.9143325053161794,.9162850744565779,.918216106880274,.9201255571995389,.9220133805339185,.9238795325112867,.9257239692688903,.9275466474543786,.9293475242268224,.9311265572577219,.9328837047320004,.9346189253489884,.9363321783233931,.9380234233862578,.9396926207859083,.9413397312888874,.942964716180876,.9445675372676047,.9461481568757504,.947706537853822,.9492426435730339,.9507564379281666,.9522478853384153,.9537169507482269,.955163599628123,.9565877979755122,.9579895123154889,.9593687097016201,.9607253577167205,.9620594244736131,.9633708786158803,.9646596893185995,.9659258262890683,.9671692597675166,.9683899605278059,.969587899878116,.97076304966162,.9719153822571454,.9730448705798238,.9741514880817275,.9752352087524931,.9762960071199334,.9773338582506355,.9783487377505475,.9793406217655515,.980309486982024,.9812553106273847,.9821780704706308,.98307774482286,.9839543125377807,.984807753012208,.9856380461865492,.9864451725452739,.987229113117374,.987989849476809,.9887273637429388,.9894416385809445,.9901326572022359,.9908004033648453,.9914448613738104,.9920660160815423,.9926638528881819,.993238357741943,.9937895171394426,.9943173181260184,.9948217482960331,.9953027957931658,.9957604493106914,.9961946980917455,.9966055319295779,.996992941167792,.9973569167005722,.9976974499728977,.9980145329807433,.9983081582712682,.9985783189429907,.9988250086459504,.9990482215818578,.99924795250423,.9994241967185149,.9995769500822006,.9997062090049132,.9998119704485015,.9998942319271075,.9999529915072262,.9999882478077495,1,.9999882478077495,.9999529915072262,.9998942319271075,.9998119704485015,.9997062090049132,.9995769500822006,.9994241967185149,.99924795250423,.9990482215818578,.9988250086459504,.9985783189429907,.9983081582712682,.9980145329807433,.9976974499728977,.9973569167005722,.996992941167792,.9966055319295779,.9961946980917455,.9957604493106914,.9953027957931658,.9948217482960331,.9943173181260184,.9937895171394426,.993238357741943,.9926638528881819,.9920660160815423,.9914448613738105,.9908004033648453,.9901326572022359,.9894416385809446,.9887273637429388,.987989849476809,.987229113117374,.9864451725452739,.9856380461865492,.984807753012208,.9839543125377807,.98307774482286,.9821780704706307,.9812553106273847,.9803094869820241,.9793406217655516,.9783487377505476,.9773338582506356,.9762960071199334,.9752352087524931,.9741514880817276,.9730448705798238,.9719153822571455,.9707630496616201,.969587899878116,.9683899605278059,.9671692597675166,.9659258262890683,.9646596893185995,.9633708786158803,.9620594244736133,.9607253577167205,.9593687097016202,.9579895123154889,.9565877979755123,.9551635996281231,.9537169507482269,.9522478853384153,.9507564379281666,.949242643573034,.9477065378538221,.9461481568757505,.9445675372676048,.942964716180876,.9413397312888873,.9396926207859084,.9380234233862579,.9363321783233931,.9346189253489885,.9328837047320006,.9311265572577219,.9293475242268225,.9275466474543786,.9257239692688904,.9238795325112867,.9220133805339185,.920125557199539,.918216106880274,.916285074456578,.9143325053161794,.9123584453530141,.9103629409661467,.9083460390586793,.90630778703665,.904248232807918,.9021674247810377,.9000654118641213,.8979422434636883,.8957979694835051,.8936326403234123,.8914463068781386,.8892390205361062,.8870108331782218,.8847617971766579,.8824919653936212,.8802013911801111,.8778901283746644,.8755582313020909,.8732057547721958,.8708327540784921,.8684392849969006,.8660254037844387,.8635911671778987,.8611366323925138,.858661857120613,.8561668995302665,.8536518182639163,.8511166724369997,.8485615216365591,.8459864259198412,.8433914458128856,.8407766423091031,.8381420768678404,.8354878114129364,.8328139083312672,.8301204304712789,.8274074411415107,.8246750041091069,.8219231835983182,.819152044288992,.8163616513150518,.8135520702629675,.8107233671702123,.8078756085237112,.8050088612582784,.802123192755044,.7992186708398695,.7962953637817556,.7933533402912352,.7903926695187593,.7874134210530723,.7844156649195758,.7813994715786824,.7783649119241601,.775312057281466,.7722409794060693,.769151750481765,.766044443118978,.7629191303530551,.7597758856425494,.756614782867493,.7534358963276608,.7502393007408243,.7470250712409959,.7437932833766611,.7405440131090045,.7372773368101241,.7339933312612353,.7306920736508675,.7273736415730488,.7240381130254827,.7206855664077148,.7173160805192896,.713929734557899,.710526608117521,.7071067811865476,.703670334145906,.7002173477671687,.6967479032106549,.6932620820235241,.6897599661378576,.6862416378687336,.6827071799122926,.6791566753437933,.6755902076156604,.6720078605555225,.6684097183642426,.6647958656139381,.6611663872459935,.6575213685690636,.6538608952570697,.6501850533471835,.6464939292378067,.6427876096865395,.6390661818081418,.635329733072485,.6315783513024975,.6278121246720986,.6240311417041269,.6202354912682602,.6164252625789255,.612600545193203,.6087614290087209,.6049080042615419,.6010403615240432,.5971585917027862,.593262786036382,.5893530360933449,.5854294337699406,.5814920712880268,.5775410411928852,.5735764363510459,.5695983499481064,.5656068754865385,.5616021067834929,.5575841379685929,.5535530634817224,.5495089780708062,.5454519767895827,.5413821549953699,.5372996083468241,.5332044328016912,.5290967246145525,.5249765803345602,.5208440968031698,.516699371151863,.5125425007998654,.5083735834518555,.5041927170956703,.49999999999999994,.49579553071207916,.49157940805537065,.48735173112724245,.48311259929663863,.4788621122017437,.47460036974764064,.47032747210396275,.46604351970253877,.4617486132350339,.45744285365058085,.4531263421534083,.44879918020046233,.4444614694990212,.4401133120043047,.43575480991707927,.43138606568125343,.4270071819814714,.4226182617406995,.4182194081178065,.4138107245051393,.40939231452609276,.4049642820326738,.40052673110306086,.3960797660391572,.39162349136413904,.38715801182000065,.3826834323650899,.37819985817164264,.3737073946233107,.3692061473126843,.36469622203881175,.3601777248047104,.3556507618148765,.35111543947278884,.34657186437840765,.3420201433256689,.3374603832999743,.33289269147567685,.32831717521356135,.3237339420583214,.31914309973603083,.3145447561516137,.30993901938630525,.30532599769511326,.30070579950427334,.29607853340870016,.2914443081694349,.2868032327110902,.28215541611928774,.2775009676380958,.2728399966674611,.26817261276063753,.263498925621611,.258819045102521,.2541330812010788,.24944114405798165,.24474334395432376,.24003979130900596,.2353305966761377,.23061587074244033,.225895724324645,.22117026836688802,.21643961393810274,.21170387222941067,.20696315455150538,.20221757233203796,.19746723711299763,.19271226054808982,.18795275440011205,.18318883053832688,.17842060093583242,.17364817766693072,.16887167290449276,.16409119891732402,.15930686806752267,.15451879280784062,.1497270856790398,.14493185930724697,.14013322640130613,.135331299750131,.13052619222005157,.12571801675216274,.12090688635966945,.11609291412523036,.11127621319829985,.1064568967924685,.10163507818280217,.09681087070317945,.09198438774362741,.0871557427476582,.08232504920959997,.07749242067193107,.07265797072261079,.0678218129924096,.06298406115223781,.05814482891047573,.0533042300102982,.04846237822700297,.04361938736533607,.038775371256816835,.03393044375706242,.029084718743111644,.02423831011074843,.01939133177182472,.014543897651583058,.009696121685978408,.004848117819001927,12246467991473532e-32,-.004848117819001238,-.009696121685978163,-.01454389765158237,-.019391331771824474,-.02423831011074774,-.029084718743111398,-.03393044375706173,-.03877537125681659,-.04361938736533583,-.048462378227003174,-.05330423001029795,-.05814482891047593,-.06298406115223758,-.06782181299240934,-.07265797072261056,-.07749242067193128,-.08232504920959974,-.08715574274765794,-.09198438774362716,-.09681087070317876,-.10163507818280193,-.10645689679246781,-.1112762131982996,-.11609291412523012,-.12090688635966965,-.1257180167521625,-.13052619222005177,-.13533129975013078,-.14013322640130632,-.14493185930724675,-.14972708567904,-.1545187928078404,-.15930686806752198,-.16409119891732377,-.16887167290449254,-.17364817766693047,-.17842060093583176,-.18318883053832663,-.1879527544001114,-.1927122605480896,-.19746723711299738,-.20221757233203816,-.20696315455150513,-.21170387222941087,-.21643961393810252,-.2211702683668878,-.22589572432464475,-.23061587074244053,-.23533059667613745,-.2400397913090053,-.2447433439543235,-.24944114405798098,-.2541330812010786,-.25881904510252035,-.2634989256216107,-.26817261276063686,-.2728399966674609,-.27750096763809556,-.2821554161192879,-.28680323271108993,-.29144430816943506,-.29607853340869994,-.30070579950427306,-.30532599769511304,-.3099390193863046,-.3145447561516135,-.3191430997360306,-.3237339420583211,-.3283171752135607,-.33289269147567657,-.3374603832999737,-.34202014332566866,-.3465718643784074,-.35111543947278906,-.35565076181487626,-.36017772480471055,-.3646962220388115,-.3692061473126845,-.3737073946233105,-.3781998581716428,-.38268343236508967,-.38715801182000004,-.3916234913641388,-.39607976603915657,-.40052673110306064,-.4049642820326732,-.40939231452609254,-.41381072450513867,-.4182194081178062,-.4226182617406993,-.4270071819814716,-.4313860656812532,-.43575480991707943,-.4401133120043045,-.444461469499021,-.4487991802004621,-.4531263421534085,-.4574428536505806,-.46174861323503374,-.46604351970253854,-.47032747210396214,-.4746003697476404,-.47886211220174313,-.4831125992966384,-.4873517311272422,-.4915794080553708,-.49579553071207894,-.5000000000000001,-.50419271709567,-.5083735834518556,-.5125425007998652,-.5166993711518633,-.5208440968031696,-.5249765803345596,-.5290967246145523,-.533204432801691,-.5372996083468239,-.5413821549953693,-.5454519767895825,-.5495089780708056,-.5535530634817222,-.5575841379685926,-.5616021067834931,-.5656068754865384,-.5695983499481065,-.5735764363510458,-.577541041192885,-.5814920712880266,-.5854294337699408,-.5893530360933448,-.5932627860363815,-.597158591702786,-.6010403615240426,-.6049080042615417,-.6087614290087203,-.6126005451932028,-.6164252625789249,-.6202354912682599,-.6240311417041268,-.6278121246720987,-.6315783513024973,-.6353297330724852,-.6390661818081416,-.6427876096865393,-.6464939292378065,-.6501850533471829,-.6538608952570695,-.6575213685690635,-.6611663872459933,-.6647958656139376,-.6684097183642425,-.6720078605555221,-.6755902076156601,-.6791566753437931,-.6827071799122927,-.6862416378687334,-.6897599661378577,-.693262082023524,-.696747903210655,-.7002173477671685,-.7036703341459061,-.7071067811865475,-.7105266081175206,-.7139297345578989,-.7173160805192892,-.7206855664077146,-.7240381130254823,-.7273736415730487,-.7306920736508671,-.7339933312612352,-.737277336810124,-.7405440131090048,-.743793283376661,-.747025071240996,-.7502393007408242,-.7534358963276607,-.7566147828674927,-.7597758856425493,-.7629191303530554,-.7660444431189779,-.7691517504817651,-.7722409794060688,-.7753120572814659,-.7783649119241597,-.7813994715786822,-.7844156649195754,-.7874134210530722,-.7903926695187589,-.7933533402912349,-.7962953637817558,-.79921867083987,-.8021231927550437,-.8050088612582785,-.8078756085237111,-.8107233671702119,-.8135520702629674,-.8163616513150515,-.8191520442889916,-.8219231835983181,-.8246750041091064,-.8274074411415104,-.830120430471279,-.8328139083312671,-.8354878114129365,-.8381420768678401,-.8407766423091032,-.8433914458128855,-.8459864259198411,-.8485615216365587,-.8511166724369996,-.8536518182639165,-.8561668995302664,-.8586618571206132,-.8611366323925135,-.8635911671778986,-.8660254037844385,-.8684392849969005,-.8708327540784918,-.8732057547721956,-.8755582313020905,-.8778901283746643,-.8802013911801112,-.8824919653936215,-.8847617971766578,-.8870108331782218,-.889239020536106,-.8914463068781383,-.8936326403234122,-.8957979694835049,-.897942243463688,-.9000654118641208,-.9021674247810375,-.9042482328079179,-.90630778703665,-.9083460390586792,-.9103629409661468,-.912358445353014,-.9143325053161795,-.9162850744565778,-.918216106880274,-.9201255571995388,-.9220133805339183,-.9238795325112865,-.9257239692688903,-.9275466474543786,-.9293475242268223,-.9311265572577219,-.9328837047320003,-.9346189253489884,-.9363321783233929,-.9380234233862578,-.9396926207859082,-.9413397312888873,-.9429647161808761,-.9445675372676049,-.9461481568757504,-.9477065378538222,-.9492426435730339,-.9507564379281666,-.9522478853384153,-.9537169507482267,-.9551635996281229,-.956587797975512,-.9579895123154888,-.9593687097016201,-.9607253577167205,-.9620594244736131,-.9633708786158804,-.9646596893185994,-.9659258262890683,-.9671692597675166,-.9683899605278059,-.9695878998781159,-.97076304966162,-.9719153822571452,-.9730448705798238,-.9741514880817276,-.975235208752493,-.9762960071199334,-.9773338582506355,-.9783487377505475,-.9793406217655514,-.980309486982024,-.9812553106273846,-.9821780704706307,-.98307774482286,-.9839543125377805,-.984807753012208,-.9856380461865493,-.9864451725452739,-.9872291131173742,-.9879898494768089,-.9887273637429387,-.9894416385809445,-.9901326572022358,-.9908004033648452,-.9914448613738104,-.9920660160815423,-.9926638528881818,-.993238357741943,-.9937895171394426,-.9943173181260184,-.994821748296033,-.9953027957931658,-.9957604493106913,-.9961946980917455,-.9966055319295779,-.996992941167792,-.9973569167005722,-.9976974499728977,-.9980145329807433,-.9983081582712682,-.9985783189429907,-.9988250086459504,-.9990482215818578,-.99924795250423,-.9994241967185149,-.9995769500822006,-.9997062090049132,-.9998119704485015,-.9998942319271076,-.9999529915072262,-.9999882478077495,-1,-.9999882478077495,-.9999529915072262,-.9998942319271076,-.9998119704485015,-.9997062090049132,-.9995769500822006,-.9994241967185149,-.99924795250423,-.9990482215818578,-.9988250086459504,-.9985783189429907,-.9983081582712682,-.9980145329807433,-.9976974499728977,-.9973569167005724,-.996992941167792,-.9966055319295779,-.9961946980917455,-.9957604493106914,-.9953027957931658,-.9948217482960331,-.9943173181260185,-.9937895171394426,-.993238357741943,-.9926638528881819,-.9920660160815424,-.9914448613738105,-.9908004033648453,-.9901326572022358,-.9894416385809446,-.9887273637429387,-.987989849476809,-.9872291131173742,-.986445172545274,-.9856380461865493,-.9848077530122081,-.9839543125377807,-.9830777448228601,-.9821780704706308,-.9812553106273846,-.9803094869820241,-.9793406217655515,-.9783487377505476,-.9773338582506355,-.9762960071199335,-.9752352087524931,-.9741514880817276,-.9730448705798239,-.9719153822571454,-.9707630496616201,-.969587899878116,-.968389960527806,-.9671692597675167,-.9659258262890684,-.9646596893185995,-.9633708786158806,-.9620594244736133,-.9607253577167206,-.9593687097016202,-.9579895123154889,-.9565877979755121,-.955163599628123,-.9537169507482268,-.9522478853384154,-.9507564379281668,-.949242643573034,-.9477065378538223,-.9461481568757506,-.944567537267605,-.9429647161808762,-.9413397312888874,-.9396926207859083,-.9380234233862579,-.936332178323393,-.9346189253489885,-.9328837047320004,-.9311265572577221,-.9293475242268224,-.9275466474543788,-.9257239692688904,-.9238795325112866,-.9220133805339186,-.9201255571995389,-.9182161068802742,-.9162850744565779,-.9143325053161796,-.9123584453530141,-.9103629409661469,-.9083460390586794,-.9063077870366503,-.9042482328079181,-.9021674247810376,-.9000654118641209,-.8979422434636882,-.895797969483505,-.8936326403234123,-.8914463068781384,-.8892390205361063,-.887010833178222,-.8847617971766579,-.8824919653936216,-.8802013911801113,-.8778901283746645,-.8755582313020907,-.8732057547721959,-.870832754078492,-.8684392849969007,-.8660254037844386,-.8635911671778989,-.8611366323925137,-.8586618571206134,-.8561668995302666,-.8536518182639167,-.8511166724369998,-.848561521636559,-.8459864259198413,-.8433914458128857,-.8407766423091034,-.8381420768678404,-.8354878114129367,-.8328139083312672,-.8301204304712791,-.8274074411415107,-.8246750041091067,-.8219231835983183,-.8191520442889918,-.8163616513150517,-.8135520702629676,-.8107233671702121,-.8078756085237113,-.8050088612582788,-.802123192755044,-.7992186708398701,-.796295363781756,-.7933533402912352,-.7903926695187591,-.7874134210530724,-.7844156649195756,-.7813994715786825,-.7783649119241599,-.7753120572814661,-.7722409794060691,-.7691517504817653,-.7660444431189781,-.7629191303530556,-.7597758856425495,-.7566147828674927,-.753435896327661,-.7502393007408246,-.7470250712409963,-.7437932833766612,-.740544013109005,-.7372773368101242,-.7339933312612357,-.7306920736508676,-.7273736415730492,-.7240381130254828,-.7206855664077145,-.7173160805192891,-.7139297345578991,-.7105266081175208,-.7071067811865477,-.7036703341459063,-.7002173477671687,-.6967479032106556,-.6932620820235246,-.6897599661378577,-.6862416378687334,-.6827071799122926,-.679156675343793,-.6755902076156605,-.6720078605555223,-.6684097183642427,-.6647958656139378,-.6611663872459935,-.6575213685690637,-.6538608952570701,-.6501850533471836,-.6464939292378064,-.6427876096865396,-.6390661818081416,-.6353297330724854,-.6315783513024976,-.627812124672099,-.624031141704127,-.6202354912682606,-.6164252625789255,-.6126005451932034,-.6087614290087209,-.6049080042615417,-.6010403615240425,-.5971585917027863,-.5932627860363818,-.589353036093345,-.585429433769941,-.5814920712880269,-.5775410411928856,-.5735764363510465,-.5695983499481065,-.5656068754865391,-.561602106783493,-.5575841379685926,-.5535530634817225,-.5495089780708059,-.5454519767895828,-.5413821549953696,-.5372996083468242,-.5332044328016913,-.5290967246145529,-.5249765803345603,-.5208440968031696,-.5166993711518632,-.5125425007998651,-.5083735834518559,-.5041927170956704,-.5000000000000004,-.49579553071207927,-.49157940805537115,-.48735173112724256,-.48311259929663913,-.4788621122017438,-.47460036974764036,-.4703274721039621,-.4660435197025389,-.46174861323503363,-.45744285365058096,-.4531263421534088,-.44879918020046244,-.4444614694990217,-.4401133120043052,-.43575480991708015,-.4313860656812539,-.42700718198147153,-.4226182617406992,-.4182194081178066,-.413810724505139,-.40939231452609287,-.40496428203267354,-.400526731103061,-.3960797660391569,-.39162349136413954,-.38715801182000076,-.3826834323650904,-.37819985817164276,-.3737073946233104,-.3692061473126848,-.36469622203881186,-.3601777248047109,-.3556507618148766,-.3511154394727894,-.34657186437840776,-.34202014332566943,-.3374603832999744,-.3328926914756765,-.32831717521356063,-.32373394205832107,-.31914309973603056,-.3145447561516138,-.3099390193863049,-.30532599769511337,-.30070579950427384,-.2960785334087003,-.29144430816943584,-.2868032327110907,-.28215541611928785,-.2775009676380955,-.2728399966674612,-.2681726127606372,-.2634989256216111,-.2588190451025207,-.2541330812010789,-.24944114405798135,-.24474334395432432,-.24003979130900607,-.23533059667613823,-.23061587074244044,-.2258957243246447,-.22117026836688813,-.21643961393810288,-.21170387222941123,-.2069631545515055,-.20221757233203852,-.19746723711299774,-.19271226054809037,-.1879527544001122,-.18318883053832655,-.17842060093583256,-.1736481776669304,-.16887167290449245,-.16409119891732413,-.15930686806752234,-.15451879280784075,-.14972708567904036,-.1449318593072471,-.14013322640130713,-.13533129975013158,-.13052619222005168,-.1257180167521624,-.12090688635966958,-.11609291412523004,-.11127621319829996,-.10645689679246818,-.10163507818280229,-.09681087070317913,-.09198438774362797,-.08715574274765832,-.08232504920960054,-.0774924206719312,-.07265797072261047,-.06782181299240972,-.06298406115223794,-.0581448289104763,-.05330423001029832,-.04846237822700354,-.043619387365336194,-.038775371256817404,-.03393044375706254,-.02908471874311221,-.02423831011074855,-.019391331771824397,-.014543897651582293,-.009696121685978531,-.004848117819001606];var Vector2_THREE=__webpack_require__(70);class Vector2 extends Vector2_THREE.Vector2{length(){return GameMath.sqrt(this.x*this.x+this.y*this.y)}angle(){let e=GameMath.atan2(this.y,this.x);return e<0&&(e+=2*Math.PI),e}distanceTo(e){return GameMath.sqrt(this.distanceToSquared(e))}rotateAround(e,t){var i=GameMath.cos(t),r=GameMath.sin(t),s=this.x-e.x,t=this.y-e.y;return this.x=s*i-t*r+e.x,this.y=s*r+t*i+e.y,this}}var Quaternion_THREE=__webpack_require__(70);class Quaternion extends Quaternion_THREE.Quaternion{setFromEuler(e,t){if(!e||!e.isEuler)throw new Error("THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.");var i=e.x,r=e.y,s=e.z,a=e.order,n=GameMath.cos(i/2),o=GameMath.cos(r/2),e=GameMath.cos(s/2),i=GameMath.sin(i/2),r=GameMath.sin(r/2),s=GameMath.sin(s/2);return"XYZ"===a?(this._x=i*o*e+n*r*s,this._y=n*r*e-i*o*s,this._z=n*o*s+i*r*e,this._w=n*o*e-i*r*s):"YXZ"===a?(this._x=i*o*e+n*r*s,this._y=n*r*e-i*o*s,this._z=n*o*s-i*r*e,this._w=n*o*e+i*r*s):"ZXY"===a?(this._x=i*o*e-n*r*s,this._y=n*r*e+i*o*s,this._z=n*o*s+i*r*e,this._w=n*o*e-i*r*s):"ZYX"===a?(this._x=i*o*e-n*r*s,this._y=n*r*e+i*o*s,this._z=n*o*s-i*r*e,this._w=n*o*e+i*r*s):"YZX"===a?(this._x=i*o*e+n*r*s,this._y=n*r*e+i*o*s,this._z=n*o*s-i*r*e,this._w=n*o*e-i*r*s):"XZY"===a&&(this._x=i*o*e-n*r*s,this._y=n*r*e-i*o*s,this._z=n*o*s+i*r*e,this._w=n*o*e+i*r*s),!1!==t&&this.onChangeCallback(),this}setFromAxisAngle(e,t){var i=t/2,t=GameMath.sin(i);return this._x=e.x*t,this._y=e.y*t,this._z=e.z*t,this._w=GameMath.cos(i),this.onChangeCallback(),this}setFromRotationMatrix(e){let t=e.elements,i=t[0],r=t[4],s=t[8],a=t[1],n=t[5],o=t[9],l=t[2],h=t[6],c=t[10],u=i+n+c,d;return 0<u?(d=.5/GameMath.sqrt(u+1),this._w=.25/d,this._x=(h-o)*d,this._y=(s-l)*d,this._z=(a-r)*d):n<i&&c<i?(d=2*GameMath.sqrt(1+i-n-c),this._w=(h-o)/d,this._x=.25*d,this._y=(r+a)/d,this._z=(s+l)/d):c<n?(d=2*GameMath.sqrt(1+n-i-c),this._w=(s-l)/d,this._x=(r+a)/d,this._y=.25*d,this._z=(o+h)/d):(d=2*GameMath.sqrt(1+c-i-n),this._w=(a-r)/d,this._x=(s+l)/d,this._y=(o+h)/d,this._z=.25*d),this.onChangeCallback(),this}length(){return GameMath.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)}slerp(e,t){if(0===t)return this;if(1===t)return this.copy(e);var i=this._x,r=this._y,s=this._z,a=this._w;let n=a*e._w+i*e._x+r*e._y+s*e._z;if(n<0?(this._w=-e._w,this._x=-e._x,this._y=-e._y,this._z=-e._z,n=-n):this.copy(e),1<=n)return this._w=a,this._x=i,this._y=r,this._z=s,this;var o=1-n*n;if(o<=Number.EPSILON){var l=1-t;return this._w=l*a+t*this._w,this._x=l*i+t*this._x,this._y=l*r+t*this._y,this._z=l*s+t*this._z,this.normalize()}e=GameMath.sqrt(o),l=GameMath.atan2(e,n),o=GameMath.sin((1-t)*l)/e,e=GameMath.sin(t*l)/e;return this._w=a*o+this._w*e,this._x=i*o+this._x*e,this._y=r*o+this._y*e,this._z=s*o+this._z*e,this.onChangeCallback(),this}}var HighBridgeHeadType,PaletteType,TheaterType,MixFileFlags,EngineType,GameResSource,GameModeType,Vector3_THREE=__webpack_require__(70);class Vector3_Vector3 extends Vector3_THREE.Vector3{applyEuler(e){return e&&e.isEuler||console.error("THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order."),this.applyQuaternion(_quaternion.setFromEuler(e))}applyAxisAngle(e,t){return this.applyQuaternion(_quaternion.setFromAxisAngle(e,t))}length(){return GameMath.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)}projectOnPlane(e){return _vector.copy(this).projectOnVector(e),this.sub(_vector)}reflect(e){return this.sub(_vector.copy(e).multiplyScalar(2*this.dot(e)))}angleTo(e){e=this.dot(e)/GameMath.sqrt(this.lengthSq()*e.lengthSq());return GameMath.acos(clamp(e,-1,1))}distanceTo(e){return GameMath.sqrt(this.distanceToSquared(e))}setFromSpherical(e){var t=GameMath.sin(e.phi)*e.radius;return this.x=t*GameMath.sin(e.theta),this.y=GameMath.cos(e.phi)*e.radius,this.z=t*GameMath.cos(e.theta),this}setFromCylindrical(e){return this.x=e.radius*GameMath.sin(e.theta),this.y=e.y,this.z=e.radius*GameMath.cos(e.theta),this}}const _quaternion=new Quaternion,_vector=new Vector3_Vector3;class Coords{static tileToWorld(e,t){return{x:e*Coords.LEPTONS_PER_TILE,y:t*Coords.LEPTONS_PER_TILE}}static vecWorldToGround(e){return new Vector2(e.x,e.z)}static vecGroundToWorld(e){return new Vector3_Vector3(e.x,0,e.y)}static tileHeightToWorld(e){return e*(Coords.LEPTONS_PER_TILE/2)*Coords.zScale}static worldToTileHeight(e){return e/(Coords.LEPTONS_PER_TILE/2*Coords.zScale)}static tile3dToWorld(e,t,i){t=Coords.tileToWorld(e,t),i=Coords.tileHeightToWorld(i);return new Vector3_Vector3(t.x,i,t.y)}static screenDistanceToWorld(e,t){return{x:Math.floor((e+2*t)/2*Coords.ISO_WORLD_SCALE),y:Math.floor((2*t-e)/2*Coords.ISO_WORLD_SCALE)}}static getWorldTileSize(){return Coords.LEPTONS_PER_TILE}}Coords.ISO_TILE_SIZE=30,Coords.LEPTONS_PER_TILE=256,Coords.ISO_WORLD_SCALE=Coords.LEPTONS_PER_TILE/Coords.ISO_TILE_SIZE,Coords.ISO_CAMERA_ALPHA=Math.PI/6,Coords.ISO_CAMERA_BETA=Math.PI/4,Coords.COS_ISO_CAMERA_BETA=GameMath.cos(Coords.ISO_CAMERA_BETA),Coords.zScale=Coords.COS_ISO_CAMERA_BETA/GameMath.cos(Coords.ISO_CAMERA_ALPHA);class TileSetEntry{constructor(e,t){this.owner=e,this.index=t,this.files=[]}addFile(e){this.files.push(e)}setAnimation(e){this.animation=e}getAnimation(){return this.animation}getTmpFile(e,t,i=!1){if(this.files.length){t=this.files[t(0,this.files.length-1)];return t.images[Math.min(e,t.images.length-1)].hasDamagedData?this.files[Math.min(i?1:0,this.files.length-1)]:t}}getRelativeTilePositions(){return this.files[0].images.map(({x:e,y:t,height:i},r)=>({subTile:r,rx:(e+2*t)/2/Coords.ISO_TILE_SIZE,ry:(2*t-e)/2/Coords.ISO_TILE_SIZE,z:i}))}}class TileSet{constructor(e,t,i){this.fileName=e,this.setName=t,this.tilesInSet=i,this.entries=[]}}class TileSetAnim{constructor(e,t,i,r){this.name=e,this.subTile=t,this.offsetX=i,this.offsetY=r}}!function(e){e[e.TopLeft=0]="TopLeft",e[e.BottomRight=1]="BottomRight",e[e.TopRight=2]="TopRight",e[e.BottomLeft=3]="BottomLeft",e[e.MiddleTlBr=4]="MiddleTlBr",e[e.MiddleTrBl=5]="MiddleTrBl"}(HighBridgeHeadType=HighBridgeHeadType||{});const highBridgeHeadNames=new Map([[HighBridgeHeadType.TopLeft,["BridgeTopLeft1","BridgeTopLeft2"]],[HighBridgeHeadType.BottomRight,["BridgeBottomRight1","BridgeBottomRight2"]],[HighBridgeHeadType.TopRight,["BridgeTopRight1","BridgeTopRight2"]],[HighBridgeHeadType.BottomLeft,["BridgeBottomLeft1","BridgeBottomLeft2"]],[HighBridgeHeadType.MiddleTlBr,["BridgeMiddle1"]],[HighBridgeHeadType.MiddleTrBl,["BridgeMiddle2"]]]);class TileSets{constructor(e){this.theaterIni=e,this.tileSets=[],this.orderedEntries=[],this.highBridgeSetNums=[this.getGeneralValue("BridgeSet"),this.getGeneralValue("WoodBridgeSet")],this.cliffSetNums=[this.getGeneralValue("CliffSet"),this.getGeneralValue("WaterCliffs"),this.getGeneralValue("DestroyableCliffs")]}getTile(e){return this.orderedEntries[e]}getTileImage(e,t,i){let r=this.getTile(e);if(!r)throw new Error(`TileNum ${e} not found`);i=r.getTmpFile(t,i);if(!i||t>=i.images.length)throw new Error(`SubTile ${t} not found`);return i.images[t]}getSetNum(e){var t=this.orderedEntries[e];if(!t)throw new Error("Invalid tileNum "+e);return this.tileSets.indexOf(t.owner)}getTileNumFromSet(i,r=0){let s=0;return this.tileSets.some((e,t)=>t===i?(s+=r,!0):(s+=e.entries.length,!1)),s}getGeneralValue(e){let t=this.theaterIni.getSection("General");if(!t)throw new Error("Missing [General] section in theather ini");return t.getNumber(e)}loadTileData(e,t){this.tileSets.length=0,this.orderedEntries.length=0,this.initTileSets(e,t),this.initAnimations()}readMaxTileNum(){let t=0,i=0;for(;;){var r="TileSet"+pad(t,"0000");let e=this.theaterIni.getSection(r);if(!e)break;t++,i+=e.getNumber("TilesInSet")}return i}initTileSets(a,n){let e=0,t;for(var i;;){if(i="TileSet"+pad(e,"0000"),t=this.theaterIni.getSection(i),!t)break;e++;let s=new TileSet(t.getString("FileName"),t.getString("SetName"),t.getNumber("TilesInSet"));this.tileSets.push(s);for(let r=1;r<=s.tilesInSet;r++){let i=new TileSetEntry(s,r-1);var o="a".charCodeAt(0);for(let t=o-1;t<="z".charCodeAt(0);t++)if(!(t>=o&&"Bridges"===s.setName)){let e=s.fileName+pad(r,"00");t>=o&&(e+=String.fromCharCode(t)),e+=n;var l=a.get(e);if(!l)break;i.addFile(l)}s.entries.push(i),this.orderedEntries.push(i)}}}initAnimations(){var r=this.theaterIni.getOrderedSections();for(let e=this.tileSets.length;e<r.length;++e){let t=r[e],i=this.tileSets.find(e=>e.setName===t.name);if(i)for(let e=1;e<=i.tilesInSet;++e){var s="Tile"+pad(e,"00"),a=s+"Anim",n=t.getString(a);n?(s=new TileSetAnim(n,t.getNumber(s+"AttachesTo"),t.getNumber(s+"XOffset"),t.getNumber(s+"YOffset")),i.entries[e-1].setAnimation(s)):console.warn(`Missing anim "${a}" for tileset `+i.setName)}}}isLAT(e){return e===this.getGeneralValue("RoughTile")||e===this.getGeneralValue("SandTile")||e===this.getGeneralValue("GreenTile")||e===this.getGeneralValue("PaveTile")}isCLAT(e){return e===this.getGeneralValue("ClearToRoughLat")||e===this.getGeneralValue("ClearToSandLat")||e===this.getGeneralValue("ClearToGreenLat")||e===this.getGeneralValue("ClearToPaveLat")}getLAT(e){return e===this.getGeneralValue("ClearToRoughLat")?this.getGeneralValue("RoughTile"):e===this.getGeneralValue("ClearToSandLat")?this.getGeneralValue("SandTile"):e===this.getGeneralValue("ClearToGreenLat")?this.getGeneralValue("GreenTile"):e===this.getGeneralValue("ClearToPaveLat")?this.getGeneralValue("PaveTile"):-1}getCLATSet(e){return e===this.getGeneralValue("RoughTile")?this.getGeneralValue("ClearToRoughLat"):e===this.getGeneralValue("SandTile")?this.getGeneralValue("ClearToSandLat"):e===this.getGeneralValue("GreenTile")?this.getGeneralValue("ClearToGreenLat"):e===this.getGeneralValue("PaveTile")?this.getGeneralValue("ClearToPaveLat"):-1}canConnectTiles(e,t){if(e===t)return!1;var i=this.getGeneralValue("GreenTile"),r=this.getGeneralValue("PaveTile"),s=this.getGeneralValue("MiscPaveTile"),a=this.getGeneralValue("ShorePieces"),n=this.getGeneralValue("WaterBridge"),o=this.getGeneralValue("PavedRoads"),l=this.getGeneralValue("Medians");return!(e===i&&t===a||t===i&&e===a)&&(!(e===i&&t===n||t===i&&e===n)&&(!(e===r&&t===o||t===r&&e===o)&&(!(e===r&&t===s||t===r&&e===s)&&!(e===r&&t===l||t===r&&e===l))))}getHighBridgeHeadType(e){for(var[t,i]of highBridgeHeadNames)for(var r of i)if(this.getGeneralValue(r)===e+1)return t}getOppositeHighBridgeHeadType(e){switch(e){case HighBridgeHeadType.TopLeft:return HighBridgeHeadType.BottomRight;case HighBridgeHeadType.TopRight:return HighBridgeHeadType.BottomLeft;case HighBridgeHeadType.BottomLeft:return HighBridgeHeadType.TopRight;case HighBridgeHeadType.BottomRight:return HighBridgeHeadType.TopLeft;case HighBridgeHeadType.MiddleTlBr:case HighBridgeHeadType.MiddleTrBl:throw new Error("Middle bridge heads can't have opposites");default:throw new Error("Unhandled headType "+e)}}isCliffTile(e){return this.cliffSetNums.includes(this.getSetNum(e))}isHighBridgeBoundaryTile(e){if(this.highBridgeSetNums.includes(this.getSetNum(e))){e=this.getTile(e),e=this.getHighBridgeHeadType(e.index);return void 0!==e&&![HighBridgeHeadType.MiddleTlBr,HighBridgeHeadType.MiddleTrBl].includes(e)}return!1}isHighBridgeMiddleTile(e){if(this.highBridgeSetNums.includes(this.getSetNum(e))){e=this.getTile(e),e=this.getHighBridgeHeadType(e.index);return void 0!==e&&[HighBridgeHeadType.MiddleTlBr,HighBridgeHeadType.MiddleTrBl].includes(e)}return!1}}!function(e){e[e.None=0]="None",e[e.Iso=1]="Iso",e[e.Unit=2]="Unit",e[e.Overlay=3]="Overlay",e[e.Anim=4]="Anim",e[e.Custom=5]="Custom",e[e.Default=6]="Default"}(PaletteType=PaletteType||{});class Theater{static factory(e,t,i,r,s){var a=s.get(i.isoPaletteName);if(!a)throw new Error(`Missing palette "${i.isoPaletteName}"`);var n=s.get(i.overlayPaletteName);if(!n)throw new Error(`Missing palette "${i.overlayPaletteName}"`);var o=s.get(i.unitPaletteName);if(!o)throw new Error(`Missing palette "${i.unitPaletteName}"`);var l=s.get("anim.pal");if(!l)throw new Error("Missing anim palette");var h=s.get(i.libPaletteName);if(!h)throw new Error("Missing lib palette "+i.libPaletteName);let c=new TileSets(t);return c.loadTileData(r,i.extension),new this(e,i,s,a,n,o,l,h,c)}constructor(e,t,i,r,s,a,n,o,l){this.type=e,this.settings=t,this.palettes=i,this.isoPalette=r,this.ovlPalette=s,this.unitPalette=a,this.animPalette=n,this.libPalette=o,this.tileSets=l}getPalette(e,t){switch(e){case PaletteType.Anim:return this.animPalette;case PaletteType.Overlay:return this.ovlPalette;case PaletteType.Unit:return this.unitPalette;case PaletteType.Custom:if("lib"===t)return this.libPalette;var i=this.palettes.get(t+".pal");if(!i)throw new Error(`Custom palette "${t}" not found`);return i;default:PaletteType.Iso;return this.isoPalette}}}!function(e){e[e.None=0]="None",e[e.Temperate=1]="Temperate",e[e.Urban=2]="Urban",e[e.Snow=4]="Snow",e[e.Lunar=8]="Lunar",e[e.Desert=16]="Desert",e[e.NewUrban=32]="NewUrban",e[e.All=63]="All"}(TheaterType=TheaterType||{});const version="0.79.1";class AudioBagFile{constructor(){this.fileData=new Map}fromVirtualFile(e,t){var i,r;for([i,r]of t.entries){var s=this.buildWavData(e.stream,r);this.fileData.set(i,s)}return this}getFileList(){return[...this.fileData.keys()]}containsFile(e){return this.fileData.has(e)}openFile(e){if(!this.containsFile(e))throw new Error(`File "${e}" not found`);return new VirtualFile(this.fileData.get(e),e)}buildWavData(e,t){let i=new DataStream;var r,s,a,n,o=0<(1&t.flags)?2:1;let l=0;0<(2&t.flags)?(i.writeString("RIFF"),i.writeUint32(t.length+36),i.writeString("WAVE"),i.writeString("fmt "),i.writeInt32(16),i.writeInt16(1),i.writeInt16(o),i.writeUint32(t.sampleRate),i.writeUint32(2*o*t.sampleRate),i.writeInt16(2*o),i.writeInt16(16),i.writeString("data"),i.writeUint32(t.length)):0<(8&t.flags)&&(r=11100*o*(t.sampleRate/22050|0),s=t.chunkSize,a=1017*(n=Math.max(2,Math.ceil(t.length/s))),n=n*s,l=n-t.length,i.writeString("RIFF"),i.writeUint32(52+n),i.writeString("WAVE"),i.writeString("fmt "),i.writeUint32(20),i.writeInt16(17),i.writeInt16(o),i.writeUint32(t.sampleRate),i.writeInt32(r),i.writeInt16(s),i.writeInt16(4),i.writeInt16(2),i.writeInt16(1017),i.writeString("fact"),i.writeUint32(4),i.writeInt32(a),i.writeString("data"),i.writeUint32(n)),e.seek(t.offset),i.writeUint8Array(e.readUint8Array(t.length));for(let e=0;e<l;e++)i.writeUint8(0);return i.seek(0),i._trimAlloc=()=>{},i}}class IdxEntry{}class IdxFile{constructor(e){this.entries=new Map,this.parse(e)}parse(t){var e=t.readCString(4);if("GABA"!==e)throw new Error(`Unable to load Idx file, did not find magic id, found ${e} instead`);e=t.readInt32();if(2!==e)throw new Error(`Unable to load Idx file, did not find magic number 2, found ${e} instead`);var i=t.readInt32();for(let e=0;e<i;e++){const s=new IdxEntry;let e=t.readString(16);var r=e.indexOf("\0");0!==r&&(e=e.substr(0,r)),s.filename=e+".wav",s.offset=t.readUint32(),s.length=t.readUint32(),s.sampleRate=t.readUint32(),s.flags=t.readUint32(),s.chunkSize=t.readUint32(),this.entries.set(s.filename,s)}}}function swapBytes(e){return e=((e=(e<<16>>>0|e>>>16)>>>0)<<8>>>0&4278255360|e>>>8&16711935)>>>0}class Blowfish{constructor(i){this.m_p=new Uint32Array([608135816,2242054355,320440878,57701188,2752067618,698298832,137296536,3964562569,1160258022,953160567,3193202383,887688300,3232508343,3380367581,1065670069,3041331479,2450970073,2306472731]),this.m_s=[new Uint32Array([3509652390,2564797868,805139163,3491422135,3101798381,1780907670,3128725573,4046225305,614570311,3012652279,134345442,2240740374,1667834072,1901547113,2757295779,4103290238,227898511,1921955416,1904987480,2182433518,2069144605,3260701109,2620446009,720527379,3318853667,677414384,3393288472,3101374703,2390351024,1614419982,1822297739,2954791486,3608508353,3174124327,2024746970,1432378464,3864339955,2857741204,1464375394,1676153920,1439316330,715854006,3033291828,289532110,2706671279,2087905683,3018724369,1668267050,732546397,1947742710,3462151702,2609353502,2950085171,1814351708,2050118529,680887927,999245976,1800124847,3300911131,1713906067,1641548236,4213287313,1216130144,1575780402,4018429277,3917837745,3693486850,3949271944,596196993,3549867205,258830323,2213823033,772490370,2760122372,1774776394,2652871518,566650946,4142492826,1728879713,2882767088,1783734482,3629395816,2517608232,2874225571,1861159788,326777828,3124490320,2130389656,2716951837,967770486,1724537150,2185432712,2364442137,1164943284,2105845187,998989502,3765401048,2244026483,1075463327,1455516326,1322494562,910128902,469688178,1117454909,936433444,3490320968,3675253459,1240580251,122909385,2157517691,634681816,4142456567,3825094682,3061402683,2540495037,79693498,3249098678,1084186820,1583128258,426386531,1761308591,1047286709,322548459,995290223,1845252383,2603652396,3431023940,2942221577,3202600964,3727903485,1712269319,422464435,3234572375,1170764815,3523960633,3117677531,1434042557,442511882,3600875718,1076654713,1738483198,4213154764,2393238008,3677496056,1014306527,4251020053,793779912,2902807211,842905082,4246964064,1395751752,1040244610,2656851899,3396308128,445077038,3742853595,3577915638,679411651,2892444358,2354009459,1767581616,3150600392,3791627101,3102740896,284835224,4246832056,1258075500,768725851,2589189241,3069724005,3532540348,1274779536,3789419226,2764799539,1660621633,3471099624,4011903706,913787905,3497959166,737222580,2514213453,2928710040,3937242737,1804850592,3499020752,2949064160,2386320175,2390070455,2415321851,4061277028,2290661394,2416832540,1336762016,1754252060,3520065937,3014181293,791618072,3188594551,3933548030,2332172193,3852520463,3043980520,413987798,3465142937,3030929376,4245938359,2093235073,3534596313,375366246,2157278981,2479649556,555357303,3870105701,2008414854,3344188149,4221384143,3956125452,2067696032,3594591187,2921233993,2428461,544322398,577241275,1471733935,610547355,4027169054,1432588573,1507829418,2025931657,3646575487,545086370,48609733,2200306550,1653985193,298326376,1316178497,3007786442,2064951626,458293330,2589141269,3591329599,3164325604,727753846,2179363840,146436021,1461446943,4069977195,705550613,3059967265,3887724982,4281599278,3313849956,1404054877,2845806497,146425753,1854211946]),new Uint32Array([1266315497,3048417604,3681880366,3289982499,290971e4,1235738493,2632868024,2414719590,3970600049,1771706367,1449415276,3266420449,422970021,1963543593,2690192192,3826793022,1062508698,1531092325,1804592342,2583117782,2714934279,4024971509,1294809318,4028980673,1289560198,2221992742,1669523910,35572830,157838143,1052438473,1016535060,1802137761,1753167236,1386275462,3080475397,2857371447,1040679964,2145300060,2390574316,1461121720,2956646967,4031777805,4028374788,33600511,2920084762,1018524850,629373528,3691585981,3515945977,2091462646,2486323059,586499841,988145025,935516892,3367335476,2599673255,2839830854,265290510,3972581182,2759138881,3795373465,1005194799,847297441,406762289,1314163512,1332590856,1866599683,4127851711,750260880,613907577,1450815602,3165620655,3734664991,3650291728,3012275730,3704569646,1427272223,778793252,1343938022,2676280711,2052605720,1946737175,3164576444,3914038668,3967478842,3682934266,1661551462,3294938066,4011595847,840292616,3712170807,616741398,312560963,711312465,1351876610,322626781,1910503582,271666773,2175563734,1594956187,70604529,3617834859,1007753275,1495573769,4069517037,2549218298,2663038764,504708206,2263041392,3941167025,2249088522,1514023603,1998579484,1312622330,694541497,2582060303,2151582166,1382467621,776784248,2618340202,3323268794,2497899128,2784771155,503983604,4076293799,907881277,423175695,432175456,1378068232,4145222326,3954048622,3938656102,3820766613,2793130115,2977904593,26017576,3274890735,3194772133,1700274565,1756076034,4006520079,3677328699,720338349,1533947780,354530856,688349552,3973924725,1637815568,332179504,3949051286,53804574,2852348879,3044236432,1282449977,3583942155,3416972820,4006381244,1617046695,2628476075,3002303598,1686838959,431878346,2686675385,1700445008,1080580658,1009431731,832498133,3223435511,2605976345,2271191193,2516031870,1648197032,4164389018,2548247927,300782431,375919233,238389289,3353747414,2531188641,2019080857,1475708069,455242339,2609103871,448939670,3451063019,1395535956,2413381860,1841049896,1491858159,885456874,4264095073,4001119347,1565136089,3898914787,1108368660,540939232,1173283510,2745871338,3681308437,4207628240,3343053890,4016749493,1699691293,1103962373,3625875870,2256883143,3830138730,1031889488,3479347698,1535977030,4236805024,3251091107,2132092099,1774941330,1199868427,1452454533,157007616,2904115357,342012276,595725824,1480756522,206960106,497939518,591360097,863170706,2375253569,3596610801,1814182875,2094937945,3421402208,1082520231,3463918190,2785509508,435703966,3908032597,1641649973,2842273706,3305899714,1510255612,2148256476,2655287854,3276092548,4258621189,236887753,3681803219,274041037,1734335097,3815195456,3317970021,1899903192,1026095262,4050517792,356393447,2410691914,3873677099,3682840055]),new Uint32Array([3913112168,2491498743,4132185628,2489919796,1091903735,1979897079,3170134830,3567386728,3557303409,857797738,1136121015,1342202287,507115054,2535736646,337727348,3213592640,1301675037,2528481711,1895095763,1721773893,3216771564,62756741,2142006736,835421444,2531993523,1442658625,3659876326,2882144922,676362277,1392781812,170690266,3921047035,1759253602,3611846912,1745797284,664899054,1329594018,3901205900,3045908486,2062866102,2865634940,3543621612,3464012697,1080764994,553557557,3656615353,3996768171,991055499,499776247,1265440854,648242737,3940784050,980351604,3713745714,1749149687,3396870395,4211799374,3640570775,1161844396,3125318951,1431517754,545492359,4268468663,3499529547,1437099964,2702547544,3433638243,2581715763,2787789398,1060185593,1593081372,2418618748,4260947970,69676912,2159744348,86519011,2512459080,3838209314,1220612927,3339683548,133810670,1090789135,1078426020,1569222167,845107691,3583754449,4072456591,1091646820,628848692,1613405280,3757631651,526609435,236106946,48312990,2942717905,3402727701,1797494240,859738849,992217954,4005476642,2243076622,3870952857,3732016268,765654824,3490871365,2511836413,1685915746,3888969200,1414112111,2273134842,3281911079,4080962846,172450625,2569994100,980381355,4109958455,2819808352,2716589560,2568741196,3681446669,3329971472,1835478071,660984891,3704678404,4045999559,3422617507,3040415634,1762651403,1719377915,3470491036,2693910283,3642056355,3138596744,1364962596,2073328063,1983633131,926494387,3423689081,2150032023,4096667949,1749200295,3328846651,309677260,2016342300,1779581495,3079819751,111262694,1274766160,443224088,298511866,1025883608,3806446537,1145181785,168956806,3641502830,3584813610,1689216846,3666258015,3200248200,1692713982,2646376535,4042768518,1618508792,1610833997,3523052358,4130873264,2001055236,3610705100,2202168115,4028541809,2961195399,1006657119,2006996926,3186142756,1430667929,3210227297,1314452623,4074634658,4101304120,2273951170,1399257539,3367210612,3027628629,1190975929,2062231137,2333990788,2221543033,2438960610,1181637006,548689776,2362791313,3372408396,3104550113,3145860560,296247880,1970579870,3078560182,3769228297,1714227617,3291629107,3898220290,166772364,1251581989,493813264,448347421,195405023,2709975567,677966185,3703036547,1463355134,2715995803,1338867538,1343315457,2802222074,2684532164,233230375,2599980071,2000651841,3277868038,1638401717,4028070440,3237316320,6314154,819756386,300326615,590932579,1405279636,3267499572,3150704214,2428286686,3959192993,3461946742,1862657033,1266418056,963775037,2089974820,2263052895,1917689273,448879540,3550394620,3981727096,150775221,3627908307,1303187396,508620638,2975983352,2726630617,1817252668,1876281319,1457606340,908771278,3720792119,3617206836,2455994898,1729034894,1080033504]),new Uint32Array([976866871,3556439503,2881648439,1522871579,1555064734,1336096578,3548522304,2579274686,3574697629,3205460757,3593280638,3338716283,3079412587,564236357,2993598910,1781952180,1464380207,3163844217,3332601554,1699332808,1393555694,1183702653,3581086237,1288719814,691649499,2847557200,2895455976,3193889540,2717570544,1781354906,1676643554,2592534050,3230253752,1126444790,2770207658,2633158820,2210423226,2615765581,2414155088,3127139286,673620729,2805611233,1269405062,4015350505,3341807571,4149409754,1057255273,2012875353,2162469141,2276492801,2601117357,993977747,3918593370,2654263191,753973209,36408145,2530585658,25011837,3520020182,2088578344,530523599,2918365339,1524020338,1518925132,3760827505,3759777254,1202760957,3985898139,3906192525,674977740,4174734889,2031300136,2019492241,3983892565,4153806404,3822280332,352677332,2297720250,60907813,90501309,3286998549,1016092578,2535922412,2839152426,457141659,509813237,4120667899,652014361,1966332200,2975202805,55981186,2327461051,676427537,3255491064,2882294119,3433927263,1307055953,942726286,933058658,2468411793,3933900994,4215176142,1361170020,2001714738,2830558078,3274259782,1222529897,1679025792,2729314320,3714953764,1770335741,151462246,3013232138,1682292957,1483529935,471910574,1539241949,458788160,3436315007,1807016891,3718408830,978976581,1043663428,3165965781,1927990952,4200891579,2372276910,3208408903,3533431907,1412390302,2931980059,4132332400,1947078029,3881505623,4168226417,2941484381,1077988104,1320477388,886195818,18198404,3786409e3,2509781533,112762804,3463356488,1866414978,891333506,18488651,661792760,1628790961,3885187036,3141171499,876946877,2693282273,1372485963,791857591,2686433993,3759982718,3167212022,3472953795,2716379847,445679433,3561995674,3504004811,3574258232,54117162,3331405415,2381918588,3769707343,4154350007,1140177722,4074052095,668550556,3214352940,367459370,261225585,2610173221,4209349473,3468074219,3265815641,314222801,3066103646,3808782860,282218597,3406013506,3773591054,379116347,1285071038,846784868,2669647154,3771962079,3550491691,2305946142,453669953,1268987020,3317592352,3279303384,3744833421,2610507566,3859509063,266596637,3847019092,517658769,3462560207,3443424879,370717030,4247526661,2224018117,4143653529,4112773975,2788324899,2477274417,1456262402,2901442914,1517677493,1846949527,2295493580,3734397586,2176403920,1280348187,1908823572,3871786941,846861322,1172426758,3287448474,3383383037,1655181056,3139813346,901632758,1897031941,2986607138,3066810236,3447102507,1393639104,373351379,950779232,625454576,3124240540,4148612726,2007998917,544563296,2244738638,2330496472,2058025392,1291430526,424198748,50039436,29584100,3605783033,2429876329,2791104160,1057563949,3255363231,3075367218,3463963227,1469046755,985887462])];for(let e=0,t=0;e<18;++e){var r=i[t++%i.length],s=i[t++%i.length],a=i[t++%i.length],n=i[t++%i.length];this.m_p[e]^=r<<24|s<<16|a<<8|n}let o=0,l=0;for(let e=0;e<18;)[o,l]=this._encrypt(o,l),this.m_p[e++]=o,this.m_p[e++]=l;for(let t=0;t<4;++t)for(let e=0;e<256;)[o,l]=this._encrypt(o,l),this.m_s[t][e++]=o,this.m_s[t][e++]=l}encrypt(e){return this.runCipher(e,this._encrypt.bind(this))}decrypt(e){return this.runCipher(e,this._decrypt.bind(this))}runCipher(e,t){let i=new Uint32Array(e.length),r=e.length/2|0,s=0;for(;0<r--;){var a=swapBytes(e[s]),n=swapBytes(e[s+1]);[a,n]=t(a,n),i[s++]=swapBytes(a),i[s++]=swapBytes(n)}return i}_encrypt(e,t){let i=e,r=t;i^=this.m_p[0];let s=!1;for(let e=1;e<=16;e++,s=!s)s?i=this.round(i,r,e):r=this.round(r,i,e);return r^=this.m_p[17],[r,i]}_decrypt(e,t){let i=e,r=t;i^=this.m_p[17];let s=!1;for(let e=16;1<=e;e--,s=!s)s?i=this.round(i,r,e):r=this.round(r,i,e);return r^=this.m_p[0],[r,i]}s(e,t){return this.m_s[t][e>>(3-t<<3)&255]}bf_f(e){return(this.s(e,0)+this.s(e,1)>>>0^this.s(e,2))+this.s(e,3)>>>0}round(e,t,i){return e^(this.bf_f(t)^this.m_p[i])}}const pubkeyStr="AihRvNoIbTn85FZRYNZRcT+i6KpU+maCsEqr3Q5q+LDB5tH7Tz2qQ38V",char2num=new Int8Array([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1]);class PublicKey{constructor(){this.key1=new Uint32Array(64),this.key2=new Uint32Array(64)}}class BlowfishKey{constructor(){this.pubkey=new PublicKey,this.glob1=new Uint32Array(64),this.glob2=new Uint32Array(130),this.glob1_hi=new Uint32Array(4),this.glob1_hi_inv=new Uint32Array(4)}init_bignum(t,e,i){for(let e=0;e<i;e++)t[e]=0;t[0]=e}move_key_to_big(e,t,i,r){let s;s=0!=(128&t[0])?255:0;const a=new Uint8Array(e.buffer,e.byteOffset);let n=4*r;for(;n>i;n--)a[n-1]=s;for(;0<n;n--)a[n-1]=t[i-n]}key_to_bignum(e,t,i){let r,s,a=0;if(2===t[a]){if(a++,0!=(128&t[a])){for(r=0,s=0;s<(127&t[a]);s++)r=(r<<8>>>0|t[a+s+1])>>>0;a+=1+(127&t[a])}else r=t[a],a++;r<=4*i&&this.move_key_to_big(e,t.subarray(a),r,i)}}len_bignum(e,t){let i=t-1;for(;0<=i&&0===e[i];)i--;return i+1}bitlen_bignum(e,t){var i;let r,s;if(0===(i=this.len_bignum(e,t)))return 0;for(r=32*i,s=2147483648;0==(s&e[i-1]);)s>>>=1,r--;return r}init_pubkey(){let e=0,t;var i;const r=new Uint8Array(256);for(this.init_bignum(this.pubkey.key2,65537,64),t=0;e<pubkeyStr.length;)i=(((char2num[pubkeyStr.charCodeAt(e++)]>>>0<<6>>>0|255&char2num[pubkeyStr.charCodeAt(e++)])>>>0<<6>>>0|255&char2num[pubkeyStr.charCodeAt(e++)])>>>0<<6>>>0|255&char2num[pubkeyStr.charCodeAt(e++)])>>>0,r[t++]=i>>16&255,r[t++]=i>>8&255,r[t++]=255&i;this.key_to_bignum(this.pubkey.key1,r,64),this.pubkey.len=this.bitlen_bignum(this.pubkey.key1,64)-1}len_predata(){var e=(this.pubkey.len-1)/8|0;return(1+(55/e|0))*(1+e)>>>0}cmp_bignum(e,t,i){for(;0<i;){if(e[--i]<t[i])return-1;if(e[i]>t[i])return 1}return 0}mov_bignum(t,i,r){for(let e=0;e<r;e++)t[e]=i[e]}shr_bignum(e,t,i){let r;var s=t/32|0;if(0<s){for(r=0;r<i-s;r++)e[r]=e[r+s];for(;r<i;r++)e[r]=0;t%=32}if(0!==t){for(r=0;r<i-1;r++)e[r]=(e[r]>>>t|e[r+1]<<32-t>>>0)>>>0;e[r]=e[r]>>>t}}shl_bignum(e,t,i){let r;var s=t/32|0;if(0<s){for(r=i-1;r>s;r--)e[r]=e[r-s];for(;0<r;r--)e[r]=0;t%=32}if(0!==t){for(r=i-1;0<r;r--)e[r]=(e[r]<<t>>>0|e[r-1]>>>32-t)>>>0;e[0]=e[0]<<t>>>0}}sub_bignum(e,t,i,r,s){var a,n;s+=s;var o=new Uint16Array(t.buffer,t.byteOffset),l=new Uint16Array(i.buffer,i.byteOffset);const h=new Uint16Array(e.buffer,e.byteOffset);let c=0;for(;-1!=--s;)a=o[c],n=l[c],h[c]=a-n-r&65535,r=0!=(a-n-r&65536)?1:0,c++;return r}sub_bignum_word(e,t,i,r,s){var a,n;let o=0;for(;-1!=--s;)a=t[o],n=i[o],e[o]=a-n-r&65535,r=0!=(a-n-r&65536)?1:0,o++;return r}inv_bignum(e,t,i){const r=new Uint32Array(64);var s;let a,n,o=0;for(this.init_bignum(r,0,i),this.init_bignum(e,0,i),n=this.bitlen_bignum(t,i),a=1<<n%32>>>0,o=((n+32)/32|0)-1,s=4*((n-1)/32|0)>>>0,r[s/4|0]=r[s/4|0]|1<<(n-1&31)>>>0;0<n;)n--,this.shl_bignum(r,1,i),-1!==this.cmp_bignum(r,t,i)&&(this.sub_bignum(r,r,t,0,i),e[o]=e[o]|a>>>0),a>>>=1,0===a&&(o--,a=2147483648);this.init_bignum(r,0,i)}inc_bignum(e,t){let i=0;for(;0==++e[i]&&0<--t;)i++}init_two_dw(e,t){this.mov_bignum(this.glob1,e,t),this.glob1_bitlen=this.bitlen_bignum(this.glob1,t),this.glob1_len_x2=(this.glob1_bitlen+15)/16|0,this.mov_bignum(this.glob1_hi,this.glob1.subarray(this.len_bignum(this.glob1,t)-2),2),this.glob1_hi_bitlen=this.bitlen_bignum(this.glob1_hi,2)-32>>>0,this.shr_bignum(this.glob1_hi,this.glob1_hi_bitlen,2),this.inv_bignum(this.glob1_hi_inv,this.glob1_hi,2),this.shr_bignum(this.glob1_hi_inv,1,2),this.glob1_hi_bitlen=(this.glob1_hi_bitlen+15)%16+1>>>0,this.inc_bignum(this.glob1_hi_inv,2),32<this.bitlen_bignum(this.glob1_hi_inv,2)&&(this.shr_bignum(this.glob1_hi_inv,1,2),this.glob1_hi_bitlen--),this.glob1_hi_inv_lo=65535&this.glob1_hi_inv[0],this.glob1_hi_inv_hi=this.glob1_hi_inv[0]>>>16&65535}mul_bignum_word(e,t,i,r){let s,a;var n=new Uint16Array(t.buffer,t.byteOffset);let o=a=0;for(s=0;s<r;s++)a=i*n[o]+e[o]+a,e[o]=65535&a,o++,a>>>=16;e[o]+=65535&a}mul_bignum(e,t,i,r){let s;var a=new Uint16Array(i.buffer,i.byteOffset);let n=new Uint16Array(e.buffer,e.byteOffset);this.init_bignum(e,0,2*r);let o=0;for(s=0;s<2*r;s++)this.mul_bignum_word(n.subarray(o),t,a[o],2*r),o++}not_bignum(e,t){let i;for(i=0;i<t;i++)e[i]=~e[i]>>>0}neg_bignum(e,t){this.not_bignum(e,t),this.inc_bignum(e,t)}get_mulword(e,t){let i=((((65535&(65535^e[t-1]))*this.glob1_hi_inv_lo+65536>>>1)+((65535^e[t-2])*this.glob1_hi_inv_hi+this.glob1_hi_inv_hi>>>1)+1>>>16)+((65535&(65535^e[t-1]))*this.glob1_hi_inv_hi>>>1)+((65535^e[t])*this.glob1_hi_inv_lo>>>1)+1>>>14)+this.glob1_hi_inv_hi*(65535^e[t])*2>>>this.glob1_hi_bitlen>>>0;return 65535<i&&(i=65535),65535&i}dec_bignum(e,t){let i=0;for(;--e[i]>>>0==4294967295&&0<--t;)i++}calc_a_bignum(e,t,r,s){let a;var n=this.glob1,o=this.glob2;if(this.mul_bignum(this.glob2,t,r,s),this.glob2[2*s]=0,(r=2*this.len_bignum(this.glob2,2*s+1))>=this.glob1_len_x2){this.inc_bignum(this.glob2,2*s+1),this.neg_bignum(this.glob2,2*s+1),a=1+r-this.glob1_len_x2;let e=new Uint16Array(o.buffer),t=a,i=1+r;for(;0!==a;a--){i--;var l=this.get_mulword(e,i);t--;var h=e.subarray(t);0<l&&(this.mul_bignum_word(h,this.glob1,l,2*s),0==(32768&e[i])&&0!==this.sub_bignum_word(h,h,new Uint16Array(n.buffer),0,2*s)&&e[i]--)}this.neg_bignum(this.glob2,s),this.dec_bignum(this.glob2,s)}this.mov_bignum(e,this.glob2,s)}clear_tmp_vars(e){this.init_bignum(this.glob1,0,e),this.init_bignum(this.glob2,0,e),this.init_bignum(this.glob1_hi_inv,0,4),this.init_bignum(this.glob1_hi,0,4),this.glob1_bitlen=0,this.glob1_hi_bitlen=0,this.glob1_len_x2=0,this.glob1_hi_inv_lo=0,this.glob1_hi_inv_hi=0}calc_a_key(e,t,i,r,s){var a,n=new Uint32Array(64);let o,l,h=0;for(this.init_bignum(e,1,s),a=this.len_bignum(r,s),this.init_two_dw(r,a),o=this.bitlen_bignum(i,a)<<24>>24,r=((o+31)/32|0)>>>0,l=1<<(o-1)%32>>>1,h+=r-1,o--,this.mov_bignum(e,t,a);-1!=--o;)0===l&&(l=2147483648,h--),this.calc_a_bignum(n,e,e,a),0!=(i[h]&l)?this.calc_a_bignum(e,n,t,a):this.mov_bignum(e,n,a),l>>>=1;this.init_bignum(n,0,a),this.clear_tmp_vars(s)}memcpy(e,t,i){let r=0;for(;0!=i--;)e[r]=t[r],r++}process_predata(e,t,i){var r=new Uint32Array(64),s=new Uint32Array(64);let a=0,n=0;for(var o=(this.pubkey.len-1)/8|0;1+o<=t;)this.init_bignum(r,0,64),this.memcpy(new Uint8Array(r.buffer),e.subarray(a),1+o),this.calc_a_key(s,r,this.pubkey.key2,this.pubkey.key1,64),this.memcpy(i.subarray(n),new Uint8Array(s.buffer),o),t-=1+o,a+=1+o,n+=o}decryptKey(e){this.init_pubkey();let t=new Uint8Array(256);return this.process_predata(e,this.len_predata(),t),t.subarray(0,56)}}class Crc32{static calculateCrc(i,e=4294967295){let r=e;for(let e=0,t=i.length;e<t;e++)r=(r>>>8^this.lookUp[255&r^i[e]])>>>0;return r=(r^e)>>>0,r}constructor(e=4294967295){this.polynomal=e,this.crc=e}append(i){for(let e=0,t=i.length;e<t;e++)this.crc=(this.crc>>>8^Crc32.lookUp[255&this.crc^i[e]])>>>0}get(){return(this.crc^this.polynomal)>>>0}}Crc32.lookUp=new Uint32Array([0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117]);class MixEntry{static hashFilename(t){var i=(t=t.toUpperCase()).length,r=i>>2;if(0!=(3&i)){t+=String.fromCharCode(i-(r<<2));let e=3-(3&i);for(;0!=e--;)t+=t[r<<2]}return Crc32.calculateCrc(binaryStringToUint8Array(t))}constructor(e,t,i){this.hash=e,this.offset=t,this.length=i}}MixEntry.size=12,function(e){e[e.Checksum=65536]="Checksum",e[e.Encrypted=131072]="Encrypted"}(MixFileFlags=MixFileFlags||{});class MixFile{constructor(e){this.stream=e,this.headerStart=84,this.index=new Map,this.parseHeader()}parseHeader(){var e=this.stream.readUint32(),t=0==(e&~(MixFileFlags.Checksum|MixFileFlags.Encrypted));if(t){if(0!=(e&MixFileFlags.Encrypted))return void(this.dataStart=this.parseRaHeader())}else this.stream.seek(0);this.dataStart=this.parseTdHeader(this.stream)}parseRaHeader(){const e=this.stream;var t=e.readUint8Array(80),i=(new BlowfishKey).decryptKey(t),r=e.readUint32Array(2);const s=new Blowfish(i);let a=new DataStream(s.decrypt(r));t=a.readUint16();a.readUint32(),e.position=this.headerStart;i=6+t*MixEntry.size,t=(3+i)/4|0,r=e.readUint32Array(t+t%2);a=new DataStream(s.decrypt(r));i=this.headerStart+i+(1+(~i>>>0)&7);return this.parseTdHeader(a),i}parseTdHeader(t){var i=t.readUint16();t.readUint32();for(let e=0;e<i;e++){var r=new MixEntry(t.readUint32(),t.readUint32(),t.readUint32());this.index.set(r.hash,r)}return t.position}containsFile(e){return this.index.has(MixEntry.hashFilename(e))}openFile(e){var t=this.index.get(MixEntry.hashFilename(e));if(!t)throw new Error(`File "${e}" not found`);return VirtualFile.factory(this.stream,e,this.dataStart+t.offset,t.length)}}!function(e){e[e.AutoDetect=0]="AutoDetect",e[e.TiberianSun=1]="TiberianSun",e[e.Firestorm=2]="Firestorm",e[e.RedAlert2=3]="RedAlert2",e[e.YurisRevenge=4]="YurisRevenge"}(EngineType=EngineType||{});class FileNotFoundError extends Error{constructor(){super(...arguments),this.name="FileNotFoundError"}}class MemArchive{constructor(){this.entries=new Map}addFile(e){this.entries.set(e.filename,e)}containsFile(e){return this.entries.has(e)}openFile(e){if(!this.containsFile(e))throw new Error(`File "${e}" not found`);return this.entries.get(e)}}class VirtualFileSystem{constructor(e,t){this.rfs=e,this.logger=t,this.allArchives=new Map,this.archivesByPriority=[]}fileExists(e){for(const t of this.archivesByPriority)if(t.containsFile(e))return!0;return!1}openFile(e){for(const t of this.archivesByPriority)if(t.containsFile(e))return t.openFile(e);throw new FileNotFoundError(`File "${e}" not found in VFS`)}addArchive(e,t){this.allArchives.has(t)||(this.allArchives.set(t,e),this.archivesByPriority.push(e)),this.logger.info(`Added archive "${t}" to VFS`)}hasArchive(e){return this.allArchives.has(e)}removeArchive(e){var t=this.allArchives.get(e);t&&(this.allArchives.delete(e),this.archivesByPriority.splice(this.archivesByPriority.indexOf(t),1),this.logger.info(`Removed archive "${e}" from VFS`))}listArchives(){return[...this.allArchives.keys()]}async addMixFile(e){await this.addArchiveByFilename(e,e=>new MixFile(e.stream))}async addBagFile(e){const i=await this.openFileWithRfs(e.replace(".bag",".idx"));await this.addArchiveByFilename(e,e=>{var t=new IdxFile(i.stream);return(new AudioBagFile).fromVirtualFile(e,t)})}async addArchiveByFilename(e,t){var i;this.allArchives.has(e)||(i=await this.openFileWithRfs(e))&&this.addArchive(t(i),e)}async openFileWithRfs(e){let t;try{t=await this.rfs.openFile(e)}catch(e){if(!(e instanceof FileNotFoundError))throw e}if(!t){if(!this.fileExists(e))throw new FileNotFoundError(`File "${e}" not found`);t=this.openFile(e)}return t}async loadImplicitMixFiles(e){this.logger.info("Initializing implicit mix files..."),e===EngineType.YurisRevenge&&await this.addMixFile("langmd.mix"),await this.addMixFile("language.mix"),e===EngineType.YurisRevenge&&await this.addMixFile("ra2md.mix"),await this.addMixFile("ra2.mix"),e===EngineType.YurisRevenge&&await this.addMixFile("cachemd.mix"),await this.addMixFile("cache.mix"),e===EngineType.YurisRevenge&&await this.addMixFile("loadmd.mix"),await this.addMixFile("load.mix"),e===EngineType.YurisRevenge&&await this.addMixFile("localmd.mix"),await this.addMixFile("local.mix"),e===EngineType.YurisRevenge&&await this.addMixFile("ntrlmd.mix"),await this.addMixFile("neutral.mix"),e===EngineType.YurisRevenge&&await this.addMixFile("audiomd.mix"),await this.addMixFile("audio.mix"),await this.addBagFile("audio.bag"),e===EngineType.YurisRevenge&&await this.addMixFile("conqmd.mix"),await this.addMixFile("conquer.mix"),e===EngineType.YurisRevenge&&await this.addMixFile("genermd.mix"),await this.addMixFile("generic.mix"),e===EngineType.YurisRevenge&&await this.addMixFile("isogenmd.mix"),await this.addMixFile("isogen.mix"),e===EngineType.YurisRevenge&&await this.addMixFile("cameomd.mix"),await this.addMixFile("cameo.mix"),e===EngineType.YurisRevenge&&await this.addMixFile("multimd.mix"),await this.addMixFile("multi.mix")}async loadExtraMixFiles(i){let r=new Set;for await(var e of this.rfs.getEntries())r.add(e.toLowerCase());for(var s of["ecache","expand","elocal"])for(let t=99;0<=t;t--){let e=[""+s+pad(t,"00")+".mix"];i===EngineType.YurisRevenge&&e.push(`${s}md${pad(t,"00")}.mix`);for(var a of e)r.has(a)&&await this.addMixFile(a)}let t=[".mmx"];i===EngineType.YurisRevenge&&t.push(".yro");for(const n of t)for(const o of r)o.endsWith(n)&&this.addArchive(new MixFile((await this.rfs.openFile(o)).stream),o)}async loadStandaloneFiles(e){let i=["ini","csf"],r=new Set(e?.exclude),s=[];for await(var a of this.rfs.getEntries()){let t=a.toLowerCase();i.some(e=>t.endsWith("."+e))&&!r.has(t)&&s.push(await this.rfs.openFile(a,!0))}if(s.length){let e=new MemArchive;for(var t of s)e.addFile(t);this.addArchive(e,"mem.archive")}}}class StorageQuotaError extends Error{constructor(e){super("Storage quota exceeded",e),this.name="StorageQuotaError"}}class NameNotAllowedError extends IOError{constructor(){super(...arguments),this.name="NameNotAllowedError"}}class RealFileSystemDir{constructor(e,t=!1){this.handle=e,this.caseSensitive=t}get name(){return this.handle.name}async*getEntries(){try{for await(var e of this.handle.keys())yield e}catch(e){if("NotFoundError"===e.name)throw new FileNotFoundError(`Directory "${this.handle.name}" not found`,{cause:e});if(e instanceof DOMException)throw new IOError(`Directory "${this.handle.name}" could not be read (${e.name})`,{cause:e});throw e}}async listEntries(){let e=[];for await(var t of this.getEntries())e.push(t);return e}async*getFileHandles(){try{for await(const e of this.handle.values())"file"===e.kind&&(yield e)}catch(e){if("NotFoundError"===e.name)throw new FileNotFoundError(`Directory "${this.handle.name}" not found`,{cause:e});if(e instanceof DOMException)throw new IOError(`Directory "${this.handle.name}" could not be read (${e.name})`,{cause:e});throw e}}async*getRawFiles(){for await(const e of this.getFileHandles())yield await e.getFile()}async containsEntry(e){return void 0!==await this.resolveEntryName(e)}async resolveEntryName(e){if(this.caseSensitive)return(await this.handle.getFileHandle(e).catch(()=>this.handle.getDirectoryHandle(e)).catch(()=>{}))?.name;for await(const t of this.getEntries())if(equalsIgnoreCase(t,e))return t}async fixEntryCase(e){if(!this.caseSensitive)for await(var t of this.getEntries())if(equalsIgnoreCase(t,e)){e=t;break}return e}async getRawFile(t,e=!1,i){let r;try{var s=e?t:await this.fixEntryCase(t);r=await this.handle.getFileHandle(s)}catch(e){if("NotFoundError"===e.name)throw new FileNotFoundError(`File "${t}" not found in directory "${this.handle.name}"`,{cause:e});if(e instanceof TypeError&&e.message.includes("not allowed"))throw new NameNotAllowedError(`File name "${t}" is not allowed`,{cause:e});if(e instanceof DOMException)throw new IOError(`File "${t}" could not be read (${e.name})`,{cause:e});throw e}t=await r.getFile();return i?new File([t],t.name,{type:i}):t}async openFile(e,t=!1){t=await this.getRawFile(e,t);return VirtualFile.fromRealFile(t)}async writeFile(i,r){r=r??(i instanceof File?i.name:i.filename);try{var s=await this.fixEntryCase(r);await this.deleteFile(s,!0);let e=await this.handle.getFileHandle(s,{create:!0}),t=await e.createWritable();try{await t.write(i instanceof File?i:new Uint8Array(i.stream.buffer,i.stream.byteOffset,i.stream.byteLength)),await t.close()}catch(e){throw await t.abort(),e}}catch(e){if("QuotaExceededError"===e.name)throw new StorageQuotaError({cause:e});if("NotFoundError"===e.name)throw new FileNotFoundError(`Directory "${this.handle.name}" not found`,{cause:e});if(e instanceof TypeError&&e.message.includes("not allowed"))throw new NameNotAllowedError(`File name "${r}" is not allowed`,{cause:e});if(e instanceof DOMException)throw new IOError(`File "${r}" could not be written (${e.name})`,{cause:e});throw e}}async deleteFile(t,i=!1){t=i?t:await this.resolveEntryName(t);if(t)try{await this.handle.removeEntry(t)}catch(e){if(i&&"NotFoundError"===e.name)return;if("QuotaExceededError"===e.name)throw new StorageQuotaError({cause:e});if(e instanceof TypeError&&e.message.includes("not allowed"))throw new NameNotAllowedError(`File name "${t}" is not allowed`,{cause:e});if(e instanceof DOMException)throw new IOError(`File "${t}" could not be deleted (${e.name})`,{cause:e});throw e}}async getDirectory(t,e=this.caseSensitive){var i=e?t:await this.fixEntryCase(t);let r;try{r=await this.handle.getDirectoryHandle(i)}catch(e){if("NotFoundError"===e.name)throw new FileNotFoundError(`Directory "${t}" not found or parent directory "${this.handle.name}" is gone`,{cause:e});if(e instanceof TypeError&&e.message.includes("not allowed"))throw new NameNotAllowedError(`Directory name "${t}" is not allowed`,{cause:e});if(e instanceof DOMException)throw new IOError(`Directory "${t}" could not be read (${e.name})`,{cause:e});throw e}return new RealFileSystemDir(r,e)}async getOrCreateDirectory(t,e=this.caseSensitive){var i=e?t:await this.fixEntryCase(t);try{return new RealFileSystemDir(await this.handle.getDirectoryHandle(i,{create:!0}),e)}catch(e){if("QuotaExceededError"===e.name)throw new StorageQuotaError({cause:e});if("NotFoundError"===e.name)throw new FileNotFoundError(`Directory "${this.handle.name}" not found"`,{cause:e});if(e instanceof TypeError&&e.message.includes("not allowed"))throw new NameNotAllowedError(`Directory name "${t}" is not allowed`,{cause:e});if(e instanceof DOMException)throw new IOError(`Directory "${t}" could not be created (${e.name})`,{cause:e});throw e}}async deleteDirectory(t,e=!1){t=await this.resolveEntryName(t);if(t)try{await this.handle.removeEntry(t,{recursive:e})}catch(e){if("QuotaExceededError"===e.name)throw new StorageQuotaError({cause:e});if("InvalidModificationError"===e.name)throw new IOError("Can't delete non-empty directory when recursive = false");if(e instanceof TypeError&&e.message.includes("not allowed"))throw new NameNotAllowedError(`Directory name "${t}" is not allowed`,{cause:e});if(e instanceof DOMException)throw new IOError(`Directory "${t}" could not be deleted (${e.name})`,{cause:e});throw e}}}class RealFileSystem{constructor(){this.directories=[]}addRootDirectoryHandle(e){this.rootDirectory=this.addDirectoryHandle(e),this.rootDirectoryHandle=e}getRootDirectoryHandle(){return this.rootDirectoryHandle}addDirectoryHandle(e){e=new RealFileSystemDir(e);return this.directories.push(e),e}addDirectory(e){this.directories.push(e)}async getDirectory(e){var t=await this.findDirectory(e);if(!t)throw new Error(`Directory "${e}" not found in real file system`);return t}async findDirectory(e){for(const t of this.directories)if(await t.containsEntry(e))return await t.getDirectory(e)}getRootDirectory(){return this.rootDirectory}async containsEntry(e){for(const t of this.directories)if(await t.containsEntry(e))return!0;return!1}async openFile(e,t=!1){for(const i of this.directories)try{return await i.openFile(e,t)}catch(e){if(!(e instanceof FileNotFoundError))throw e}throw new FileNotFoundError(`File "${e}" not found in real file system`)}async getRawFile(e){for(const t of this.directories)if(await t.containsEntry(e))return await t.getRawFile(e);throw new Error(`File "${e}" not found in real file system`)}async*getEntries(){for(var e of this.directories)for await(var t of e.getEntries())yield t}}class LazyResourceCollection{constructor(e){this.resourceFactory=e,this.resources=new Map}setVfs(e){this.vfs=e}set(e,t){this.resources.set(e,t)}has(e){return!!this.resources.has(e)||(this.vfs?.fileExists(e)??!1)}get(e){let t;return t=this.resources.get(e),!t&&this.vfs?.fileExists(e)&&(t=this.resourceFactory(this.vfs.openFile(e)),this.resources.set(e,t)),t}clear(e){e?this.resources.delete(e):this.resources.clear()}}const chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function encode(t){let i="";for(let e=0;e<t.length;e+=3)i+=chars[t[e]>>2],i+=chars[(3&t[e])<<4|t[e+1]>>4],i+=chars[(15&t[e+1])<<2|t[e+2]>>6],i+=chars[63&t[e+2]];return t.length%3==2?i=i.substring(0,i.length-1)+"=":t.length%3==1&&(i=i.substring(0,i.length-2)+"=="),i}function decode(i){let r=new Uint8Array(256);for(let e=0;e<chars.length;e++)r[chars.charCodeAt(e)]=e;let e=.75*i.length;"="===i[i.length-1]&&(e--,"="===i[i.length-2]&&e--);let s=new Uint8Array(e);for(let e=0,t=0;e<i.length;e+=4){var a=r[i.charCodeAt(e)],n=r[i.charCodeAt(e+1)],o=r[i.charCodeAt(e+2)],l=r[i.charCodeAt(e+3)];s[t++]=a<<2|n>>4,s[t++]=(15&n)<<4|o>>2,s[t++]=(3&o)<<6|63&l}return s}function changeBitDepth(r,e,s,t){if(-1<["32f","64"].indexOf(e)&&-1<["32f","64"].indexOf(t))s.set(r);else{validateBitDepth_(e),validateBitDepth_(t);let i=getBitDepthFunction_(e,t);var a={oldMin:Math.pow(2,parseInt(e,10))/2,newMin:Math.pow(2,parseInt(t,10))/2,oldMax:Math.pow(2,parseInt(e,10))/2-1,newMax:Math.pow(2,parseInt(t,10))/2-1};sign8Bit_(e,r,!0);for(let e=0,t=r.length;e<t;e++)s[e]=i(r[e],a);sign8Bit_(t,s,!1)}}function intToInt_(e,t){return e=0<e?parseInt(e/t.oldMax*t.newMax,10):parseInt(e/t.oldMin*t.newMin,10)}function floatToInt_(e,t){return parseInt(0<e?e*t.newMax:e*t.newMin,10)}function intToFloat_(e,t){return 0<e?e/t.oldMax:e/t.oldMin}function getBitDepthFunction_(e,t){let i=function(e){return e};return e!=t&&(i=["32f","64"].includes(e)?floatToInt_:["32f","64"].includes(t)?intToFloat_:intToInt_),i}function validateBitDepth_(e){if("32f"!=e&&"64"!=e&&(parseInt(e,10)<"8"||"53"<parseInt(e,10)))throw new Error("Invalid bit depth.")}function sign8Bit_(e,i,t){if("8"==e){var r=t?-128:128;for(let e=0,t=i.length;e<t;e++)i[e]=i[e]+=r}}const INDEX_TABLE=[-1,-1,-1,-1,2,4,6,8,-1,-1,-1,-1,2,4,6,8],STEP_TABLE=[7,8,9,10,11,12,13,14,16,17,19,21,23,25,28,31,34,37,41,45,50,55,60,66,73,80,88,97,107,118,130,143,157,173,190,209,230,253,279,307,337,371,408,449,494,544,598,658,724,796,876,963,1060,1166,1282,1411,1552,1707,1878,2066,2272,2499,2749,3024,3327,3660,4026,4428,4871,5358,5894,6484,7132,7845,8630,9493,10442,11487,12635,13899,15289,16818,18500,20350,22385,24623,27086,29794,32767];function imaadpcm_encode(i){var r={index:0,predicted:0,step:7};let s=new Uint8Array(i.length),a=[],n=0,o=0;for(let e=0,t=i.length;e<t;e++)e%505==0&&0!=e&&(s.set(encodeBlock(a,r),n),n+=256,a=[],o++),a.push(i[e]);let e=i.length/2;return e%2&&e++,s.slice(0,e+512+4*o)}function imaadpcm_decode(t,e=256){var i={index:0,predicted:0,step:7};let r=new Int16Array(2*t.length),s=[],a=0,n=t.length,o=0;for(;0<n;){var l=Math.min(n,e);for(let e=0;e<l;e++)s.push(t[o]),o++;var h=decodeBlock(s,i);r.set(h,a),a+=h.length,s=[],n-=e}return r.slice(0,a)}function encodeBlock(i,r){let s=blockHead_(i[0],r);for(let e=3,t=i.length;e<t;e+=2){var a=encodeSample_(i[e],r),n=encodeSample_(i[e+1],r);s.push(n<<4|a)}return s}function decodeBlock(i,r){r.predicted=sign_(i[1]<<8|i[0]),r.index=i[2],r.step=STEP_TABLE[r.index];let s=[r.predicted];for(let e=4,t=i.length;e<t;e++){var a=i[e],n=a>>4;s.push(decodeSample_(n<<4^a,r)),s.push(decodeSample_(n,r))}return s}function sign_(e){return 32767<e?e-65536:e}function encodeSample_(e,t){let i=e-t.predicted,r=0;0<=i?r=0:(r=8,i=-i);let s=STEP_TABLE[t.index],a=s>>3;return i>s&&(r|=4,i-=s,a+=s),s>>=1,i>s&&(r|=2,i-=s,a+=s),s>>=1,i>s&&(r|=1,a+=s),updateEncoder_(r,a,t),r}function updateEncoder_(e,t,i){8&e?i.predicted-=t:i.predicted+=t,i.predicted<-32768?i.predicted=-32768:32767<i.predicted&&(i.predicted=32767),i.index+=INDEX_TABLE[7&e],i.index<0?i.index=0:88<i.index&&(i.index=88)}function decodeSample_(e,t){let i=0;return 4&e&&(i+=t.step),2&e&&(i+=t.step>>1),1&e&&(i+=t.step>>2),i+=t.step>>3,8&e&&(i=-i),t.predicted+=i,32767<t.predicted?t.predicted=32767:t.predicted<-32768&&(t.predicted=-32768),updateDecoder_(e,t),t.predicted}function updateDecoder_(e,t){t.index+=INDEX_TABLE[e],t.index<0?t.index=0:88<t.index&&(t.index=88),t.step=STEP_TABLE[t.index]}function blockHead_(e,t){encodeSample_(e,t);let i=[];return i.push(255&e),i.push(e>>8&255),i.push(t.index),i.push(0),i}const LOG_TABLE=[1,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7];function encodeSample(e){let t;var i,r=~(e=-32768==e?-32767:e)>>8&128;return r||(e*=-1),32635<e&&(e=32635),t=256<=e?(i=LOG_TABLE[e>>8&127])<<4|e>>i+3&15:e>>4,85^t^r}function decodeSample(e){let t=0;0!=(128&(e^=85))&&(e&=-129,t=-1);var i=4+((240&e)>>4);let r=0;return r=4!=i?1<<i|(15&e)<<i-4|1<<i-5:e<<1|1,r=0===t?r:-r,8*r*-1}function alaw_encode(i){let r=new Uint8Array(i.length);for(let e=0,t=i.length;e<t;e++)r[e]=encodeSample(i[e]);return r}function alaw_decode(i){let r=new Int16Array(i.length);for(let e=0,t=i.length;e<t;e++)r[e]=decodeSample(i[e]);return r}const BIAS=132,CLIP=32635,encodeTable=[0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7],decodeTable=[0,132,396,924,1980,4092,8316,16764];function mulaw_encodeSample(e){var t=e>>8&128;return 0!=t&&(e=-e),(e+=BIAS)>CLIP&&(e=CLIP),~(t|(t=encodeTable[e>>7&255])<<4|e>>t+3&15)}function mulaw_decodeSample(e){var t,i;let r;return t=128&(e=~e),i=e>>4&7,e=15&e,r=decodeTable[i]+(e<<3+i),0!=t&&(r=-r),r}function mulaw_encode(i){let r=new Uint8Array(i.length);for(let e=0,t=i.length;e<t;e++)r[e]=mulaw_encodeSample(i[e]);return r}function mulaw_decode(i){let r=new Int16Array(i.length);for(let e=0,t=i.length;e<t;e++)r[e]=mulaw_decodeSample(i[e]);return r}function endianness(t,i,r=0,s=t.length){for(let e=r;e<s;e+=i)swap_(t,i,e)}function swap_(t,i,r){i--;for(let e=0;e<i;e++){var s=t[r+e];t[r+e]=t[r+i],t[r+i]=s,i--}}function unpack(o,e=0,t=o.length){let l="";for(let n=e;n<t;){let i=128,r=191,s=!1,a=o[n++];if(0<=a&&a<=127)l+=String.fromCharCode(a);else{let t=0;194<=a&&a<=223?t=1:224<=a&&a<=239?(t=2,224===o[n]&&(i=160),237===o[n]&&(r=159)):240<=a&&a<=244?(t=3,240===o[n]&&(i=144),244===o[n]&&(r=143)):s=!0,a&=(1<<8-t-1)-1;for(let e=0;e<t;e++)(o[n]<i||o[n]>r)&&(s=!0),a=a<<6|63&o[n],n++;s?l+=String.fromCharCode(65533):a<=65535?l+=String.fromCharCode(a):(a-=65536,l+=String.fromCharCode(55296+(a>>10&1023),56320+(1023&a)))}}return l}function pack(e,i,r=0){let s=0;for(var t=e.length;s<t;){var a=e.codePointAt(s);if(a<128)i[r]=a,r++;else{let e=0,t=0;for(a<=2047?(e=1,t=192):a<=65535?(e=2,t=224):a<=1114111&&(e=3,t=240,s++),i[r]=(a>>6*e)+t,r++;0<e;)i[r]=128|a>>6*(e-1)&63,r++,e--}s++}return r}const BYTE_POW_TABLE=new Array(8).fill(0).map((e,t)=>Math.pow(2,8*t));class IntParser{constructor(e,t=!1){this.bits=e,this.offset=Math.ceil(e/8),this.max=Math.pow(2,e)-1,this.min=0,this.unpack=this.unpack_,t&&(this.max=Math.pow(2,e)/2-1,this.min=-this.max-1,this.unpack=this.unpackSigned_)}pack(i,r,s=0){r=this.clamp_(Math.round(r));for(let e=0,t=this.offset;e<t;e++)i[s]=255&Math.floor(r/BYTE_POW_TABLE[e]),s++;return s}unpack_(t,i=0){let r=0;for(let e=0;e<this.offset;e++)r+=t[i+e]*BYTE_POW_TABLE[e];return r}unpackSigned_(e,t=0){return this.sign_(this.unpack_(e,t))}clamp_(e){return e>this.max?this.max:e<this.min?this.min:e}sign_(e){return e>this.max&&(e-=2*this.max+2),e}}class FloatParser{constructor(e,t){this.offset=Math.ceil((e+t)/8),this.ebits=e,this.fbits=t,this.bias=(1<<e-1)-1,this.biasP2=Math.pow(2,this.bias+1),this.ebitsFbits=e+t,this.fbias=Math.pow(2,-(8*this.offset-1-e))}pack(e,t,i){var r=((t=+(t=Math.abs(t)>this.biasP2-2*this.ebitsFbits?t<0?-1/0:1/0:t))||1/t)<0||t<0?1:0;t=Math.abs(t);let s=Math.min(Math.floor(Math.log(t)/Math.LN2),1023),a=roundToEven(t/Math.pow(2,s)*Math.pow(2,this.fbits));return t!=t?(a=Math.pow(2,this.fbits-1),s=(1<<this.ebits)-1):0!==t&&(t>=Math.pow(2,1-this.bias)?(2<=a/Math.pow(2,this.fbits)&&(s+=1,a=1),a=s>this.bias?(s=(1<<this.ebits)-1,0):(s+=this.bias,roundToEven(a)-Math.pow(2,this.fbits))):(a=roundToEven(t/Math.pow(2,1-this.bias-this.fbits)),s=0)),this.packFloatBits_(e,i,r,s,a)}unpack(t,i){var e=(1<<this.ebits)-1;let r,s="";for(let e=this.offset-1;0<=e;e--){var a=t[e+i].toString(2);s+="00000000".substring(a.length)+a}var n="1"==s.charAt(0)?-1:1;s=s.substring(1);let o=parseInt(s.substring(0,this.ebits),2);return s=s.substring(this.ebits),o==e?0!==parseInt(s,2)?NaN:1/0*n:(r=0===o?(o+=1,parseInt(s,2)):parseInt("1"+s,2),n*r*this.fbias*Math.pow(2,o-this.bias))}packFloatBits_(e,t,i,r,s){let a=[];a.push(i);for(let e=this.ebits;0<e;--e)a[e]=r%2?1:0,r=Math.floor(r/2);var n=a.length;for(let e=this.fbits;0<e;--e)a[n+e]=s%2?1:0,s=Math.floor(s/2);let o=a.join(""),l=this.offset+t-1,h=t;for(;l>=t;)e[l]=parseInt(o.substring(0,8),2),o=o.substring(8),l--,h++;return h}}function roundToEven(e){var t=Math.floor(e),e=e-t;return!(e<.5)&&(.5<e||t%2)?t+1:t}function unpackString(e,t=0,i=e.length){return unpack(e,t,i)}function packString(e){var t=[];return pack(e,t),t}function packStringTo(e,t,i=0){return pack(e,t,i)}function packArrayTo(e,t,i,r=0){let s=getParser_((t=t||{}).bits,t.fp,t.signed);var a=Math.ceil(t.bits/8);let n=0;for(var o=r,l=e.length;n<l;n++)r=s.pack(i,e[n],r);return t.be&&endianness(i,a,o,r),r}function unpackArrayTo(e,t,i,r=0,s=e.length){var a,n=getParser_((t=t||{}).bits,t.fp,t.signed);s=getUnpackLen_(e,r,s,n.offset),t.be?(a=copyBuffer_(e),t.be&&endianness(a,n.offset,r,s),unpack_(a,i,r,s,n)):unpack_(e,i,r,s,n)}function packTo(e,t,i,r=0){return packArrayTo([e],t,i,r)}function binary_pack(e,t){var i=[];return packTo(e,t,i,0),i}function binary_unpack(e,t,i=0){var r=[];return unpackArrayTo(e,t,r,i,i+Math.ceil(t.bits/8)),r[0]}function unpack_(i,r,s,a,n){var o=n.offset;for(let e=0,t=s;t<a;t+=o,e++)r[e]=n.unpack(i,t)}function copyBuffer_(e){return new Uint8Array(e)}function getUnpackLen_(e,t,i,r){return i-(i-t)%r}function getParser_(e,t,i){return t&&32==e?new FloatParser(8,23):t&&64==e?new FloatParser(11,52):new IntParser(e,i)}class RIFFFile{constructor(){this.container="",this.chunkSize=0,this.format="",this.signature=null,this.head=0,this.uInt32={bits:32,be:!1},this.supported_containers=["RIFF","RIFX"]}setSignature(e){if(this.head=0,this.container=this.readString(e,4),-1===this.supported_containers.indexOf(this.container))throw Error("Not a supported format.");this.uInt32.be="RIFX"===this.container,this.chunkSize=this.readUInt32(e),this.format=this.readString(e,4),this.signature={chunkId:this.container,chunkSize:this.chunkSize,format:this.format,subChunks:this.getSubChunksIndex_(e)}}findChunk(t,i=!1){var r=this.signature.subChunks;let s=[];for(let e=0;e<r.length;e++)if(r[e].chunkId==t){if(!i)return r[e];s.push(r[e])}return"LIST"==t&&s.length?s:null}readString(e,t){var i=unpackString(e,this.head,this.head+t);return this.head+=t,i}readUInt32(e){e=binary_unpack(e,this.uInt32,this.head);return this.head+=4,e}getSubChunksIndex_(e){let t=[],i=this.head;for(;i<=e.length-8;)t.push(this.getSubChunkIndex_(e,i)),i+=8+t[t.length-1].chunkSize,i=i%2?i+1:i;return t}getSubChunkIndex_(e,t){let i={chunkId:this.getChunkId_(e,t),chunkSize:this.getChunkSize_(e,t)};return"LIST"==i.chunkId?(i.format=unpackString(e,t+8,t+12),this.head+=4,i.subChunks=this.getSubChunksIndex_(e)):(e=i.chunkSize%2?i.chunkSize+1:i.chunkSize,this.head=t+8+e,i.chunkData={start:t+8,end:this.head}),i}getChunkId_(e,t){return this.head+=4,unpackString(e,t,t+4)}getChunkSize_(e,t){return this.head+=4,binary_unpack(e,this.uInt32,t+4)}}class WaveFileReader extends RIFFFile{constructor(){super(),this.supported_containers.push("RF64"),this.fmt={chunkId:"",chunkSize:0,audioFormat:0,numChannels:0,sampleRate:0,byteRate:0,blockAlign:0,bitsPerSample:0,cbSize:0,validBitsPerSample:0,dwChannelMask:0,subformat:[]},this.fact={chunkId:"",chunkSize:0,dwSampleLength:0},this.cue={chunkId:"",chunkSize:0,dwCuePoints:0,points:[]},this.smpl={chunkId:"",chunkSize:0,dwManufacturer:0,dwProduct:0,dwSamplePeriod:0,dwMIDIUnityNote:0,dwMIDIPitchFraction:0,dwSMPTEFormat:0,dwSMPTEOffset:0,dwNumSampleLoops:0,dwSamplerData:0,loops:[]},this.bext={chunkId:"",chunkSize:0,description:"",originator:"",originatorReference:"",originationDate:"",originationTime:"",timeReference:[0,0],version:0,UMID:"",loudnessValue:0,loudnessRange:0,maxTruePeakLevel:0,maxMomentaryLoudness:0,maxShortTermLoudness:0,reserved:"",codingHistory:""},this.iXML={chunkId:"",chunkSize:0,value:""},this.ds64={chunkId:"",chunkSize:0,riffSizeHigh:0,riffSizeLow:0,dataSizeHigh:0,dataSizeLow:0,originationTime:0,sampleCountHigh:0,sampleCountLow:0},this.data={chunkId:"",chunkSize:0,samples:new Uint8Array(0)},this.LIST=[],this.junk={chunkId:"",chunkSize:0,chunkData:[]},this._PMX={chunkId:"",chunkSize:0,value:""},this.uInt16={bits:16,be:!1,signed:!1,fp:!1}}fromBuffer(e,t=!0){if(this.clearHeaders(),this.setSignature(e),this.uInt16.be=this.uInt32.be,"WAVE"!=this.format)throw Error('Could not find the "WAVE" format identifier');this.readDs64Chunk_(e),this.readFmtChunk_(e),this.readFactChunk_(e),this.readBextChunk_(e),this.readiXMLChunk_(e),this.readCueChunk_(e),this.readSmplChunk_(e),this.readDataChunk_(e,t),this.readJunkChunk_(e),this.readLISTChunk_(e),this.read_PMXChunk_(e)}clearHeaders(){var e=new WaveFileReader;Object.assign(this.fmt,e.fmt),Object.assign(this.fact,e.fact),Object.assign(this.cue,e.cue),Object.assign(this.smpl,e.smpl),Object.assign(this.bext,e.bext),Object.assign(this.iXML,e.iXML),Object.assign(this.ds64,e.ds64),Object.assign(this.data,e.data),this.LIST=[],Object.assign(this.junk,e.junk),Object.assign(this._PMX,e._PMX)}readFmtChunk_(e){var t=this.findChunk("fmt ");if(!t)throw Error('Could not find the "fmt " chunk');this.head=t.chunkData.start,this.fmt.chunkId=t.chunkId,this.fmt.chunkSize=t.chunkSize,this.fmt.audioFormat=this.readUInt16_(e),this.fmt.numChannels=this.readUInt16_(e),this.fmt.sampleRate=this.readUInt32(e),this.fmt.byteRate=this.readUInt32(e),this.fmt.blockAlign=this.readUInt16_(e),this.fmt.bitsPerSample=this.readUInt16_(e),this.readFmtExtension_(e)}readFmtExtension_(e){16<this.fmt.chunkSize&&(this.fmt.cbSize=this.readUInt16_(e),18<this.fmt.chunkSize&&(this.fmt.validBitsPerSample=this.readUInt16_(e),20<this.fmt.chunkSize&&(this.fmt.dwChannelMask=this.readUInt32(e),this.fmt.subformat=[this.readUInt32(e),this.readUInt32(e),this.readUInt32(e),this.readUInt32(e)])))}readFactChunk_(e){var t=this.findChunk("fact");t&&(this.head=t.chunkData.start,this.fact.chunkId=t.chunkId,this.fact.chunkSize=t.chunkSize,this.fact.dwSampleLength=this.readUInt32(e))}readCueChunk_(t){var e=this.findChunk("cue ");if(e){this.head=e.chunkData.start,this.cue.chunkId=e.chunkId,this.cue.chunkSize=e.chunkSize,this.cue.dwCuePoints=this.readUInt32(t);for(let e=0;e<this.cue.dwCuePoints;e++)this.cue.points.push({dwName:this.readUInt32(t),dwPosition:this.readUInt32(t),fccChunk:this.readString(t,4),dwChunkStart:this.readUInt32(t),dwBlockStart:this.readUInt32(t),dwSampleOffset:this.readUInt32(t)})}}readSmplChunk_(t){var e=this.findChunk("smpl");if(e){this.head=e.chunkData.start,this.smpl.chunkId=e.chunkId,this.smpl.chunkSize=e.chunkSize,this.smpl.dwManufacturer=this.readUInt32(t),this.smpl.dwProduct=this.readUInt32(t),this.smpl.dwSamplePeriod=this.readUInt32(t),this.smpl.dwMIDIUnityNote=this.readUInt32(t),this.smpl.dwMIDIPitchFraction=this.readUInt32(t),this.smpl.dwSMPTEFormat=this.readUInt32(t),this.smpl.dwSMPTEOffset=this.readUInt32(t),this.smpl.dwNumSampleLoops=this.readUInt32(t),this.smpl.dwSamplerData=this.readUInt32(t);for(let e=0;e<this.smpl.dwNumSampleLoops;e++)this.smpl.loops.push({dwName:this.readUInt32(t),dwType:this.readUInt32(t),dwStart:this.readUInt32(t),dwEnd:this.readUInt32(t),dwFraction:this.readUInt32(t),dwPlayCount:this.readUInt32(t)})}}readDataChunk_(e,t){var i=this.findChunk("data");if(!i)throw Error('Could not find the "data" chunk');this.data.chunkId="data",this.data.chunkSize=i.chunkSize,t&&(this.data.samples=e.slice(i.chunkData.start,i.chunkData.end))}readBextChunk_(e){var t=this.findChunk("bext");t&&(this.head=t.chunkData.start,this.bext.chunkId=t.chunkId,this.bext.chunkSize=t.chunkSize,this.bext.description=this.readString(e,256),this.bext.originator=this.readString(e,32),this.bext.originatorReference=this.readString(e,32),this.bext.originationDate=this.readString(e,10),this.bext.originationTime=this.readString(e,8),this.bext.timeReference=[this.readUInt32(e),this.readUInt32(e)],this.bext.version=this.readUInt16_(e),this.bext.UMID=this.readString(e,64),this.bext.loudnessValue=this.readUInt16_(e),this.bext.loudnessRange=this.readUInt16_(e),this.bext.maxTruePeakLevel=this.readUInt16_(e),this.bext.maxMomentaryLoudness=this.readUInt16_(e),this.bext.maxShortTermLoudness=this.readUInt16_(e),this.bext.reserved=this.readString(e,180),this.bext.codingHistory=this.readString(e,this.bext.chunkSize-602))}readiXMLChunk_(e){var t=this.findChunk("iXML");t&&(this.head=t.chunkData.start,this.iXML.chunkId=t.chunkId,this.iXML.chunkSize=t.chunkSize,this.iXML.value=unpackString(e,this.head,this.head+this.iXML.chunkSize))}readDs64Chunk_(e){var t=this.findChunk("ds64");if(t)this.head=t.chunkData.start,this.ds64.chunkId=t.chunkId,this.ds64.chunkSize=t.chunkSize,this.ds64.riffSizeHigh=this.readUInt32(e),this.ds64.riffSizeLow=this.readUInt32(e),this.ds64.dataSizeHigh=this.readUInt32(e),this.ds64.dataSizeLow=this.readUInt32(e),this.ds64.originationTime=this.readUInt32(e),this.ds64.sampleCountHigh=this.readUInt32(e),this.ds64.sampleCountLow=this.readUInt32(e);else if("RF64"==this.container)throw Error('Could not find the "ds64" chunk')}readLISTChunk_(t){var i=this.findChunk("LIST",!0);if(null!==i)for(let e=0;e<i.length;e++){var r=i[e];this.LIST.push({chunkId:r.chunkId,chunkSize:r.chunkSize,format:r.format,subChunks:[]});for(let e=0;e<r.subChunks.length;e++)this.readLISTSubChunks_(r.subChunks[e],r.format,t)}}readLISTSubChunks_(e,t,i){"adtl"==t?-1<["labl","note","ltxt"].indexOf(e.chunkId)&&this.readLISTadtlSubChunks_(i,e):"INFO"==t&&this.readLISTINFOSubChunks_(i,e)}readLISTadtlSubChunks_(e,t){this.head=t.chunkData.start;let i={chunkId:t.chunkId,chunkSize:t.chunkSize,dwName:this.readUInt32(e)};"ltxt"==t.chunkId?(i.dwSampleLength=this.readUInt32(e),i.dwPurposeID=this.readUInt32(e),i.dwCountry=this.readUInt16_(e),i.dwLanguage=this.readUInt16_(e),i.dwDialect=this.readUInt16_(e),i.dwCodePage=this.readUInt16_(e),i.value=""):i.value=this.readZSTR_(e,this.head),this.LIST[this.LIST.length-1].subChunks.push(i)}readLISTINFOSubChunks_(e,t){this.head=t.chunkData.start,this.LIST[this.LIST.length-1].subChunks.push({chunkId:t.chunkId,chunkSize:t.chunkSize,value:this.readZSTR_(e,this.head)})}readJunkChunk_(e){var t=this.findChunk("junk");t&&(this.junk={chunkId:t.chunkId,chunkSize:t.chunkSize,chunkData:[].slice.call(e.slice(t.chunkData.start,t.chunkData.end))})}read_PMXChunk_(e){var t=this.findChunk("_PMX");t&&(this.head=t.chunkData.start,this._PMX.chunkId=t.chunkId,this._PMX.chunkSize=t.chunkSize,this._PMX.value=unpackString(e,this.head,this.head+this._PMX.chunkSize))}readZSTR_(t,i=0){for(let e=i;e<t.length&&(this.head++,0!==t[e]);e++);return unpackString(t,i,this.head-1)}readUInt16_(e){e=binary_unpack(e,this.uInt16,this.head);return this.head+=2,e}}function writeString(e,t){let i=packString(e);for(let e=i.length;e<t;e++)i.push(0);return i}class WaveFileParser extends WaveFileReader{toBuffer(){this.uInt16.be="RIFX"===this.container,this.uInt32.be=this.uInt16.be;var t=[this.getJunkBytes_(),this.getDs64Bytes_(),this.getBextBytes_(),this.getiXMLBytes_(),this.getFmtBytes_(),this.getFactBytes_(),packString(this.data.chunkId),binary_pack(this.data.samples.length,this.uInt32),this.data.samples,this.getCueBytes_(),this.getSmplBytes_(),this.getLISTBytes_(),this.get_PMXBytes_()];let i=0;for(let e=0;e<t.length;e++)i+=t[e].length;let r=new Uint8Array(i+12),s=0;s=packStringTo(this.container,r,s),s=packTo(i+4,this.uInt32,r,s),s=packStringTo(this.format,r,s);for(let e=0;e<t.length;e++)r.set(t[e],s),s+=t[e].length;return r}getBextBytes_(){let e=[];return this.enforceBext_(),this.bext.chunkId&&(this.bext.chunkSize=602+this.bext.codingHistory.length,e=e.concat(packString(this.bext.chunkId),binary_pack(602+this.bext.codingHistory.length,this.uInt32),writeString(this.bext.description,256),writeString(this.bext.originator,32),writeString(this.bext.originatorReference,32),writeString(this.bext.originationDate,10),writeString(this.bext.originationTime,8),binary_pack(this.bext.timeReference[0],this.uInt32),binary_pack(this.bext.timeReference[1],this.uInt32),binary_pack(this.bext.version,this.uInt16),writeString(this.bext.UMID,64),binary_pack(this.bext.loudnessValue,this.uInt16),binary_pack(this.bext.loudnessRange,this.uInt16),binary_pack(this.bext.maxTruePeakLevel,this.uInt16),binary_pack(this.bext.maxMomentaryLoudness,this.uInt16),binary_pack(this.bext.maxShortTermLoudness,this.uInt16),writeString(this.bext.reserved,180),writeString(this.bext.codingHistory,this.bext.codingHistory.length))),this.enforceByteLen_(e),e}enforceBext_(){for(var e in this.bext)if(this.bext.hasOwnProperty(e)&&this.bext[e]&&"timeReference"!=e){this.bext.chunkId="bext";break}(this.bext.timeReference[0]||this.bext.timeReference[1])&&(this.bext.chunkId="bext")}getiXMLBytes_(){let e=[];var t;return this.iXML.chunkId&&(t=packString(this.iXML.value),this.iXML.chunkSize=t.length,e=e.concat(packString(this.iXML.chunkId),binary_pack(this.iXML.chunkSize,this.uInt32),t)),this.enforceByteLen_(e),e}getDs64Bytes_(){let e=[];return this.ds64.chunkId&&(e=e.concat(packString(this.ds64.chunkId),binary_pack(this.ds64.chunkSize,this.uInt32),binary_pack(this.ds64.riffSizeHigh,this.uInt32),binary_pack(this.ds64.riffSizeLow,this.uInt32),binary_pack(this.ds64.dataSizeHigh,this.uInt32),binary_pack(this.ds64.dataSizeLow,this.uInt32),binary_pack(this.ds64.originationTime,this.uInt32),binary_pack(this.ds64.sampleCountHigh,this.uInt32),binary_pack(this.ds64.sampleCountLow,this.uInt32))),this.enforceByteLen_(e),e}getCueBytes_(){let e=[];var t;return this.cue.chunkId&&(t=this.getCuePointsBytes_(),e=e.concat(packString(this.cue.chunkId),binary_pack(t.length+4,this.uInt32),binary_pack(this.cue.dwCuePoints,this.uInt32),t)),this.enforceByteLen_(e),e}getCuePointsBytes_(){let t=[];for(let e=0;e<this.cue.dwCuePoints;e++)t=t.concat(binary_pack(this.cue.points[e].dwName,this.uInt32),binary_pack(this.cue.points[e].dwPosition,this.uInt32),packString(this.cue.points[e].fccChunk),binary_pack(this.cue.points[e].dwChunkStart,this.uInt32),binary_pack(this.cue.points[e].dwBlockStart,this.uInt32),binary_pack(this.cue.points[e].dwSampleOffset,this.uInt32));return t}getSmplBytes_(){let e=[];var t;return this.smpl.chunkId&&(t=this.getSmplLoopsBytes_(),e=e.concat(packString(this.smpl.chunkId),binary_pack(t.length+36,this.uInt32),binary_pack(this.smpl.dwManufacturer,this.uInt32),binary_pack(this.smpl.dwProduct,this.uInt32),binary_pack(this.smpl.dwSamplePeriod,this.uInt32),binary_pack(this.smpl.dwMIDIUnityNote,this.uInt32),binary_pack(this.smpl.dwMIDIPitchFraction,this.uInt32),binary_pack(this.smpl.dwSMPTEFormat,this.uInt32),binary_pack(this.smpl.dwSMPTEOffset,this.uInt32),binary_pack(this.smpl.dwNumSampleLoops,this.uInt32),binary_pack(this.smpl.dwSamplerData,this.uInt32),t)),this.enforceByteLen_(e),e}getSmplLoopsBytes_(){let t=[];for(let e=0;e<this.smpl.dwNumSampleLoops;e++)t=t.concat(binary_pack(this.smpl.loops[e].dwName,this.uInt32),binary_pack(this.smpl.loops[e].dwType,this.uInt32),binary_pack(this.smpl.loops[e].dwStart,this.uInt32),binary_pack(this.smpl.loops[e].dwEnd,this.uInt32),binary_pack(this.smpl.loops[e].dwFraction,this.uInt32),binary_pack(this.smpl.loops[e].dwPlayCount,this.uInt32));return t}getFactBytes_(){let e=[];return this.fact.chunkId&&(e=e.concat(packString(this.fact.chunkId),binary_pack(this.fact.chunkSize,this.uInt32),binary_pack(this.fact.dwSampleLength,this.uInt32))),this.enforceByteLen_(e),e}getFmtBytes_(){if(this.fmt.chunkId){var e=[].concat(packString(this.fmt.chunkId),binary_pack(this.fmt.chunkSize,this.uInt32),binary_pack(this.fmt.audioFormat,this.uInt16),binary_pack(this.fmt.numChannels,this.uInt16),binary_pack(this.fmt.sampleRate,this.uInt32),binary_pack(this.fmt.byteRate,this.uInt32),binary_pack(this.fmt.blockAlign,this.uInt16),binary_pack(this.fmt.bitsPerSample,this.uInt16),this.getFmtExtensionBytes_());return this.enforceByteLen_(e),e}throw Error('Could not find the "fmt " chunk')}getFmtExtensionBytes_(){let e=[];return 16<this.fmt.chunkSize&&(e=e.concat(binary_pack(this.fmt.cbSize,this.uInt16))),18<this.fmt.chunkSize&&(e=e.concat(binary_pack(this.fmt.validBitsPerSample,this.uInt16))),20<this.fmt.chunkSize&&(e=e.concat(binary_pack(this.fmt.dwChannelMask,this.uInt32))),24<this.fmt.chunkSize&&(e=e.concat(binary_pack(this.fmt.subformat[0],this.uInt32),binary_pack(this.fmt.subformat[1],this.uInt32),binary_pack(this.fmt.subformat[2],this.uInt32),binary_pack(this.fmt.subformat[3],this.uInt32))),e}getLISTBytes_(){let t=[];for(let e=0;e<this.LIST.length;e++){var i=this.getLISTSubChunksBytes_(this.LIST[e].subChunks,this.LIST[e].format);t=t.concat(packString(this.LIST[e].chunkId),binary_pack(i.length+4,this.uInt32),packString(this.LIST[e].format),i)}return this.enforceByteLen_(t),t}getLISTSubChunksBytes_(i,r){let s=[];for(let e=0,t=i.length;e<t;e++)"INFO"==r?s=s.concat(this.getLISTINFOSubChunksBytes_(i[e])):"adtl"==r&&(s=s.concat(this.getLISTadtlSubChunksBytes_(i[e]))),this.enforceByteLen_(s);return s}getLISTINFOSubChunksBytes_(e){let t=[];var i=writeString(e.value,e.value.length);return t=t.concat(packString(e.chunkId),binary_pack(i.length+1,this.uInt32),i),t.push(0),t}getLISTadtlSubChunksBytes_(e){let t=[];var i;return-1<["labl","note"].indexOf(e.chunkId)?(i=writeString(e.value,e.value.length),t=t.concat(packString(e.chunkId),binary_pack(i.length+4+1,this.uInt32),binary_pack(e.dwName,this.uInt32),i),t.push(0)):"ltxt"==e.chunkId&&(t=t.concat(this.getLtxtChunkBytes_(e))),t}getLtxtChunkBytes_(e){return[].concat(packString(e.chunkId),binary_pack(e.value.length+20,this.uInt32),binary_pack(e.dwName,this.uInt32),binary_pack(e.dwSampleLength,this.uInt32),binary_pack(e.dwPurposeID,this.uInt32),binary_pack(e.dwCountry,this.uInt16),binary_pack(e.dwLanguage,this.uInt16),binary_pack(e.dwDialect,this.uInt16),binary_pack(e.dwCodePage,this.uInt16),writeString(e.value,e.value.length))}get_PMXBytes_(){let e=[];var t;return this._PMX.chunkId&&(t=packString(this._PMX.value),this._PMX.chunkSize=t.length,e=e.concat(packString(this._PMX.chunkId),binary_pack(this._PMX.chunkSize,this.uInt32),t)),this.enforceByteLen_(e),e}getJunkBytes_(){let e=[];return this.junk.chunkId?e.concat(packString(this.junk.chunkId),binary_pack(this.junk.chunkData.length,this.uInt32),this.junk.chunkData):(this.enforceByteLen_(e),e)}enforceByteLen_(e){e.length%2&&e.push(0)}}function interleave(s){let a=[];if(0<s.length)if(s[0].constructor!==Number){a=new Float64Array(s[0].length*s.length);for(let i=0,e=s[0].length,r=0;i<e;i++)for(let e=0,t=s.length;e<t;e++,r++)a[r]=s[e][i]}else a=s;return a}function deInterleave(r,s,t=Float64Array){let a=[];for(let e=0;e<s;e++)a[e]=new t(r.length/s);for(let i=0;i<s;i++)for(let e=i,t=0;e<r.length;e+=s,t++)a[i][t]=r[e];return a}function validateNumChannels(e,t){return!(e<1||65535<e*t/8)}function validateSampleRate(e,t,i){return!(i<1||4294967295<e*(t/8)*i)}class WaveFileCreator extends WaveFileParser{constructor(){super(),this.bitDepth="0",this.dataType={bits:0,be:!1},this.WAV_AUDIO_FORMATS={4:17,8:1,"8a":6,"8m":7,16:1,24:1,32:1,"32f":3,64:3}}fromScratch(e,t,i,r,s){s=s||{},this.clearHeaders(),this.newWavFile_(e,t,i,r,s)}fromBuffer(e,t=!0){super.fromBuffer(e,t),this.bitDepthFromFmt_(),this.updateDataType_()}toBuffer(){return this.validateWavHeader_(),super.toBuffer()}getSamples(e=!1,t=Float64Array){var i=new t(this.data.samples.length/(this.dataType.bits/8));return unpackArrayTo(this.data.samples,this.dataType,i,0,this.data.samples.length),!e&&1<this.fmt.numChannels?deInterleave(i,this.fmt.numChannels,t):i}getSample(e){if((e*=this.dataType.bits/8)+this.dataType.bits/8>this.data.samples.length)throw new Error("Range error");return binary_unpack(this.data.samples.slice(e,e+this.dataType.bits/8),this.dataType)}setSample(e,t){if((e*=this.dataType.bits/8)+this.dataType.bits/8>this.data.samples.length)throw new Error("Range error");packTo(t,this.dataType,this.data.samples,e,!0)}getiXML(){return this.iXML.value}setiXML(e){if("string"!=typeof e)throw new TypeError("iXML value must be a string.");this.iXML.value=e,this.iXML.chunkId="iXML"}get_PMX(){return this._PMX.value}set_PMX(e){if("string"!=typeof e)throw new TypeError("_PMX value must be a string.");this._PMX.value=e,this._PMX.chunkId="_PMX"}newWavFile_(e,t,i,r,s){s.container||(s.container="RIFF"),this.container=s.container,this.bitDepth=i,r=interleave(r),this.updateDataType_();var a=this.dataType.bits/8;this.data.samples=new Uint8Array(r.length*a),packArrayTo(r,this.dataType,this.data.samples,0,!0),this.makeWavHeader_(i,e,t,a,this.data.samples.length,s),this.data.chunkId="data",this.data.chunkSize=this.data.samples.length,this.validateWavHeader_()}makeWavHeader_(e,t,i,r,s,a){"4"==e?this.createADPCMHeader_(e,t,i,r,s,a):"8a"==e||"8m"==e?this.createALawMulawHeader_(e,t,i,r,s,a):-1==Object.keys(this.WAV_AUDIO_FORMATS).indexOf(e)||2<t?this.createExtensibleHeader_(e,t,i,r,s,a):this.createPCMHeader_(e,t,i,r,s,a)}createPCMHeader_(e,t,i,r,s,a){this.container=a.container,this.chunkSize=36+s,this.format="WAVE",this.bitDepth=e,this.fmt={chunkId:"fmt ",chunkSize:16,audioFormat:this.WAV_AUDIO_FORMATS[e]||65534,numChannels:t,sampleRate:i,byteRate:t*r*i,blockAlign:t*r,bitsPerSample:parseInt(e,10),cbSize:0,validBitsPerSample:0,dwChannelMask:0,subformat:[]}}createADPCMHeader_(e,t,i,r,s,a){this.createPCMHeader_(e,t,i,r,s,a),this.chunkSize=40+s,this.fmt.chunkSize=20,this.fmt.byteRate=4055,this.fmt.blockAlign=256,this.fmt.bitsPerSample=4,this.fmt.cbSize=2,this.fmt.validBitsPerSample=505,this.fact={chunkId:"fact",chunkSize:4,dwSampleLength:2*s}}createExtensibleHeader_(e,t,i,r,s,a){this.createPCMHeader_(e,t,i,r,s,a),this.chunkSize=60+s,this.fmt.chunkSize=40,this.fmt.bitsPerSample=1+(parseInt(e,10)-1|7),this.fmt.cbSize=22,this.fmt.validBitsPerSample=parseInt(e,10),this.fmt.dwChannelMask=dwChannelMask_(t),this.fmt.subformat=[1,1048576,2852126848,1905997824]}createALawMulawHeader_(e,t,i,r,s,a){this.createPCMHeader_(e,t,i,r,s,a),this.chunkSize=40+s,this.fmt.chunkSize=20,this.fmt.cbSize=2,this.fmt.validBitsPerSample=8,this.fact={chunkId:"fact",chunkSize:4,dwSampleLength:s}}bitDepthFromFmt_(){3===this.fmt.audioFormat&&32===this.fmt.bitsPerSample?this.bitDepth="32f":6===this.fmt.audioFormat?this.bitDepth="8a":7===this.fmt.audioFormat?this.bitDepth="8m":this.bitDepth=this.fmt.bitsPerSample.toString()}validateBitDepth_(){if(this.WAV_AUDIO_FORMATS[this.bitDepth])return!0;if(8<parseInt(this.bitDepth,10)&&parseInt(this.bitDepth,10)<54)return!0;throw new Error("Invalid bit depth.")}updateDataType_(){this.dataType={bits:1+(parseInt(this.bitDepth,10)-1|7),fp:"32f"==this.bitDepth||"64"==this.bitDepth,signed:"8"!=this.bitDepth,be:"RIFX"==this.container},-1<["4","8a","8m"].indexOf(this.bitDepth)&&(this.dataType.bits=8,this.dataType.signed=!1)}validateWavHeader_(){if(this.validateBitDepth_(),!validateNumChannels(this.fmt.numChannels,this.fmt.bitsPerSample))throw new Error("Invalid number of channels.");if(!validateSampleRate(this.fmt.numChannels,this.fmt.bitsPerSample,this.fmt.sampleRate))throw new Error("Invalid sample rate.")}}function dwChannelMask_(e){let t=0;return 1===e?t=4:2===e?t=3:4===e?t=51:6===e?t=63:8===e&&(t=1599),t}class WaveFileTagEditor extends WaveFileCreator{getTag(e){e=this.getTagIndex_(e);return null!==e.TAG?this.LIST[e.LIST].subChunks[e.TAG].value:null}setTag(e,t){e=fixRIFFTag_(e);var i=this.getTagIndex_(e);null!==i.TAG?(this.LIST[i.LIST].subChunks[i.TAG].chunkSize=t.length+1,this.LIST[i.LIST].subChunks[i.TAG].value=t):null!==i.LIST?this.LIST[i.LIST].subChunks.push({chunkId:e,chunkSize:t.length+1,value:t}):(this.LIST.push({chunkId:"LIST",chunkSize:8+t.length+1,format:"INFO",subChunks:[]}),this.LIST[this.LIST.length-1].subChunks.push({chunkId:e,chunkSize:t.length+1,value:t}))}deleteTag(e){e=this.getTagIndex_(e);return null!==e.TAG&&(this.LIST[e.LIST].subChunks.splice(e.TAG,1),!0)}listTags(){var i=this.getLISTIndex("INFO");let r={};if(null!==i)for(let e=0,t=this.LIST[i].subChunks.length;e<t;e++)r[this.LIST[i].subChunks[e].chunkId]=this.LIST[i].subChunks[e].value;return r}getLISTIndex(i){for(let e=0,t=this.LIST.length;e<t;e++)if(this.LIST[e].format==i)return e;return null}getTagIndex_(r){let s={LIST:null,TAG:null};for(let i=0,e=this.LIST.length;i<e;i++)if("INFO"==this.LIST[i].format){s.LIST=i;for(let e=0,t=this.LIST[i].subChunks.length;e<t;e++)if(this.LIST[i].subChunks[e].chunkId==r){s.TAG=e;break}break}return s}}function fixRIFFTag_(i){if(i.constructor!==String)throw new Error("Invalid tag name.");if(i.length<4)for(let e=0,t=4-i.length;e<t;e++)i+=" ";return i}class WaveFileCueEditor extends WaveFileTagEditor{listCuePoints(){let i=this.getCuePoints_();for(let e=0,t=i.length;e<t;e++)i[e].position=i[e].dwSampleOffset/this.fmt.sampleRate*1e3,i[e].dwSampleLength?(i[e].end=i[e].dwSampleLength/this.fmt.sampleRate*1e3,i[e].end+=i[e].position):i[e].end=null,delete i[e].value;return i}setCuePoint(e){this.cue.chunkId="cue ",e.label||(e.label="");var t=this.getCuePoints_();this.clearLISTadtl_(),this.cue.points=[],e.dwSampleOffset=e.position*this.fmt.sampleRate/1e3,e.dwSampleLength=0,e.end&&(e.dwSampleLength=e.end*this.fmt.sampleRate/1e3-e.dwSampleOffset),0===t.length?this.setCuePoint_(e,1):this.setCuePointInOrder_(t,e),this.cue.dwCuePoints=this.cue.points.length}deleteCuePoint(t){this.cue.chunkId="cue ";var i=this.getCuePoints_();this.clearLISTadtl_();var r=this.cue.points.length;this.cue.points=[];for(let e=0;e<r;e++)e+1!==t&&this.setCuePoint_(i[e],e+1);this.cue.dwCuePoints=this.cue.points.length,this.cue.dwCuePoints?this.cue.chunkId="cue ":(this.cue.chunkId="",this.clearLISTadtl_())}updateLabel(i,r){var s=this.getLISTIndex("adtl");if(null!==s)for(let e=0,t=this.LIST[s].subChunks.length;e<t;e++)this.LIST[s].subChunks[e].dwName==i&&(this.LIST[s].subChunks[e].value=r)}getCuePoints_(){let i=[];for(let t=0;t<this.cue.points.length;t++){var r=this.cue.points[t];let e=this.getDataForCuePoint_(r.dwName);e.label=e.value||"",e.dwPosition=r.dwPosition,e.fccChunk=r.fccChunk,e.dwChunkStart=r.dwChunkStart,e.dwBlockStart=r.dwBlockStart,e.dwSampleOffset=r.dwSampleOffset,i.push(e)}return i}getDataForCuePoint_(e){var t=this.getLISTIndex("adtl"),i={};return null!==t&&this.getCueDataFromLIST_(i,t,e),i}getCueDataFromLIST_(i,r,s){for(let e=0,t=this.LIST[r].subChunks.length;e<t;e++){var a;this.LIST[r].subChunks[e].dwName==s&&(a=this.LIST[r].subChunks[e],i.value=a.value||i.value,i.dwName=a.dwName||0,i.dwSampleLength=a.dwSampleLength||0,i.dwPurposeID=a.dwPurposeID||0,i.dwCountry=a.dwCountry||0,i.dwLanguage=a.dwLanguage||0,i.dwDialect=a.dwDialect||0,i.dwCodePage=a.dwCodePage||0)}}setCuePoint_(e,t){this.cue.points.push({dwName:t,dwPosition:e.dwPosition||0,fccChunk:e.fccChunk||"data",dwChunkStart:e.dwChunkStart||0,dwBlockStart:e.dwBlockStart||0,dwSampleOffset:e.dwSampleOffset}),this.setLabl_(e,t)}setCuePointInOrder_(t,i){let r=!1;for(let e=0;e<t.length;e++)t[e].dwSampleOffset>i.dwSampleOffset&&!r?(this.setCuePoint_(i,e+1),this.setCuePoint_(t[e],e+2),r=!0):this.setCuePoint_(t[e],r?e+2:e+1);r||this.setCuePoint_(i,this.cue.points.length+1)}clearLISTadtl_(){for(let e=0,t=this.LIST.length;e<t;e++)"adtl"==this.LIST[e].format&&this.LIST.splice(e)}setLabl_(e,t){let i=this.getLISTIndex("adtl");null===i&&(this.LIST.push({chunkId:"LIST",chunkSize:4,format:"adtl",subChunks:[]}),i=this.LIST.length-1),this.setLabelText_(i,e,t),e.dwSampleLength&&this.setLtxtChunk_(i,e,t)}setLabelText_(e,t,i){this.LIST[e].subChunks.push({chunkId:"labl",chunkSize:4,dwName:i,value:t.label}),this.LIST[e].chunkSize+=12}setLtxtChunk_(e,t,i){this.LIST[e].subChunks.push({chunkId:"ltxt",chunkSize:20,dwName:i,dwSampleLength:t.dwSampleLength,dwPurposeID:t.dwPurposeID||0,dwCountry:t.dwCountry||0,dwLanguage:t.dwLanguage||0,dwDialect:t.dwDialect||0,dwCodePage:t.dwCodePage||0,value:t.label}),this.LIST[e].chunkSize+=28}}class Interpolator{constructor(e,t,i){this.length_=e,this.scaleFactor_=(e-1)/t,this.interpolate=this.sinc,"point"===i.method?this.interpolate=this.point:"linear"===i.method?this.interpolate=this.linear:"cubic"===i.method&&(this.interpolate=this.cubic),this.tangentFactor_=1-Math.max(0,Math.min(1,i.tension||0)),this.sincFilterSize_=i.sincFilterSize||1,this.kernel_=sincKernel_(i.sincWindow||window_)}point(e,t){return this.getClippedInput_(Math.round(this.scaleFactor_*e),t)}linear(e,t){e=this.scaleFactor_*e;var i=Math.floor(e);return(1-(e-=i))*this.getClippedInput_(i,t)+e*this.getClippedInput_(i+1,t)}cubic(e,t){e=this.scaleFactor_*e;var i=Math.floor(e),r=[this.getTangent_(i,t),this.getTangent_(i+1,t)],s=[this.getClippedInput_(i,t),this.getClippedInput_(i+1,t)],t=(e-=i)*e,i=e*t;return(2*i-3*t+1)*s[0]+(i-2*t+e)*r[0]+(-2*i+3*t)*s[1]+(i-t)*r[1]}sinc(t,i){t=this.scaleFactor_*t;var e=Math.floor(t),r=e-this.sincFilterSize_+1,s=e+this.sincFilterSize_;let a=0;for(let e=r;e<=s;e++)a+=this.kernel_(t-e)*this.getClippedInput_(e,i);return a}getTangent_(e,t){return this.tangentFactor_*(this.getClippedInput_(e+1,t)-this.getClippedInput_(e-1,t))/2}getClippedInput_(e,t){return 0<=e&&e<this.length_?t[e]:0}}function window_(e){return Math.exp(-e/2*e/2)}function sincKernel_(t){return function(e){return sinc_(e)*t(e)}}function sinc_(e){return 0===e?1:Math.sin(Math.PI*e)/(Math.PI*e)}class FIRLPF{constructor(t,e,i){var r=2*Math.PI*i/e;let s=0;this.filters=[];for(let e=0;e<=t;e++)e-t/2==0?this.filters[e]=r:(this.filters[e]=Math.sin(r*(e-t/2))/(e-t/2),this.filters[e]*=.54-.46*Math.cos(2*Math.PI*e/t)),s+=this.filters[e];for(let e=0;e<=t;e++)this.filters[e]/=s;this.z=this.initZ_()}filter(e){this.z.buf[this.z.pointer]=e;let i=0;for(let e=0,t=this.z.buf.length;e<t;e++)i+=this.filters[e]*this.z.buf[(this.z.pointer+e)%this.z.buf.length];return this.z.pointer=(this.z.pointer+1)%this.z.buf.length,i}reset(){this.z=this.initZ_()}initZ_(){let t=[];for(let e=0;e<this.filters.length-1;e++)t.push(0);return{buf:t,pointer:0}}}class ButterworthLPF{constructor(t,i,r){let s=[];for(let e=0;e<t;e++)s.push(this.getCoeffs_({Fs:i,Fc:r,Q:.5/Math.sin(Math.PI/(2*t)*(e+.5))}));this.stages=[];for(let e=0;e<s.length;e++)this.stages[e]={b0:s[e].b[0],b1:s[e].b[1],b2:s[e].b[2],a1:s[e].a[0],a2:s[e].a[1],k:s[e].k,z:[0,0]}}filter(e){let i=e;for(let e=0,t=this.stages.length;e<t;e++)i=this.runStage_(e,i);return i}getCoeffs_(e){let t={a:[],b:[]};e=this.preCalc_(e,t);return t.k=1,t.b.push((1-e.cw)/(2*e.a0)),t.b.push(2*t.b[0]),t.b.push(t.b[0]),t}preCalc_(e,t){let i={};var r=2*Math.PI*e.Fc/e.Fs;return i.alpha=Math.sin(r)/(2*e.Q),i.cw=Math.cos(r),i.a0=1+i.alpha,t.a0=i.a0,t.a.push(-2*i.cw/i.a0),t.k=1,t.a.push((1-i.alpha)/i.a0),i}runStage_(e,t){var i=t*this.stages[e].k-this.stages[e].a1*this.stages[e].z[0]-this.stages[e].a2*this.stages[e].z[1],t=this.stages[e].b0*i+this.stages[e].b1*this.stages[e].z[0]+this.stages[e].b2*this.stages[e].z[1];return this.stages[e].z[1]=this.stages[e].z[0],this.stages[e].z[0]=i,t}reset(){for(let e=0;e<this.stages.length;e++)this.stages[e].z=[0,0]}}const DEFAULT_LPF_USE={point:!1,linear:!1,cubic:!0,sinc:!0},DEFAULT_LPF_ORDER={IIR:16,FIR:71},DEFAULT_LPF={IIR:ButterworthLPF,FIR:FIRLPF};function resample(e,t,i,r=null){r=r||{};var s=new Float64Array(e.length*((i-t)/t+1));r.method=r.method||"cubic";var a=new Interpolator(e.length,s.length,{method:r.method,tension:r.tension||0,sincFilterSize:r.sincFilterSize||6,sincWindow:r.sincWindow||void 0,clip:r.clip||"mirror"});if(void 0===r.LPF&&(r.LPF=DEFAULT_LPF_USE[r.method]),r.LPF){r.LPFType=r.LPFType||"IIR";const n=DEFAULT_LPF[r.LPFType];t<i?upsample_(e,s,a,new n(r.LPForder||DEFAULT_LPF_ORDER[r.LPFType],i,t/2)):downsample_(e,s,a,new n(r.LPForder||DEFAULT_LPF_ORDER[r.LPFType],t,i/2))}else resample_(e,s,a);return s}function resample_(i,r,s){for(let e=0,t=r.length;e<t;e++)r[e]=s.interpolate(e,i)}function upsample_(i,r,s,a){for(let e=0,t=r.length;e<t;e++)r[e]=a.filter(s.interpolate(e,i));a.reset();for(let e=r.length-1;0<=e;e--)r[e]=a.filter(r[e])}function downsample_(i,e,t,r){for(let e=0,t=i.length;e<t;e++)i[e]=r.filter(i[e]);r.reset();for(let e=i.length-1;0<=e;e--)i[e]=r.filter(i[e]);resample_(i,e,t)}class WaveFileConverter extends WaveFileCueEditor{toRIFF(){var e=new Float64Array(outputSize_(this.data.samples.length,this.dataType.bits/8));unpackArrayTo(this.data.samples,this.dataType,e,0,this.data.samples.length),this.fromExisting_(this.fmt.numChannels,this.fmt.sampleRate,this.bitDepth,e,{container:"RIFF"})}toRIFX(){var e=new Float64Array(outputSize_(this.data.samples.length,this.dataType.bits/8));unpackArrayTo(this.data.samples,this.dataType,e,0,this.data.samples.length),this.fromExisting_(this.fmt.numChannels,this.fmt.sampleRate,this.bitDepth,e,{container:"RIFX"})}toIMAADPCM(){if(8e3!==this.fmt.sampleRate)throw new Error("Only 8000 Hz files can be compressed as IMA-ADPCM.");if(1!==this.fmt.numChannels)throw new Error("Only mono files can be compressed as IMA-ADPCM.");this.assure16Bit_();var e=new Int16Array(outputSize_(this.data.samples.length,2));unpackArrayTo(this.data.samples,this.dataType,e,0,this.data.samples.length),this.fromExisting_(this.fmt.numChannels,this.fmt.sampleRate,"4",imaadpcm_encode(e),{container:this.correctContainer_()})}fromIMAADPCM(e="16"){let s;if(1<this.fmt.numChannels){if(2<this.fmt.numChannels)throw new Error("Only 1 or 2 channels are supported");var a=this.data.samples.length/2;let t=new Uint8Array(a),i=new Uint8Array(a),r=0;for(let e=0;e<a;e++)e&&e%4==0&&(r+=4),t[e]=this.data.samples[r+e],i[e]=this.data.samples[r+e+4];s=[imaadpcm_decode(t,this.fmt.blockAlign/2),imaadpcm_decode(i,this.fmt.blockAlign/2)]}else s=imaadpcm_decode(this.data.samples,this.fmt.blockAlign);this.fromExisting_(this.fmt.numChannels,this.fmt.sampleRate,"16",s,{container:this.correctContainer_()}),"16"!=e&&this.toBitDepth(e)}toALaw(){this.assure16Bit_();var e=new Int16Array(outputSize_(this.data.samples.length,2));unpackArrayTo(this.data.samples,this.dataType,e,0,this.data.samples.length),this.fromExisting_(this.fmt.numChannels,this.fmt.sampleRate,"8a",alaw_encode(e),{container:this.correctContainer_()})}fromALaw(e="16"){this.fromExisting_(this.fmt.numChannels,this.fmt.sampleRate,"16",alaw_decode(this.data.samples),{container:this.correctContainer_()}),"16"!=e&&this.toBitDepth(e)}toMuLaw(){this.assure16Bit_();var e=new Int16Array(outputSize_(this.data.samples.length,2));unpackArrayTo(this.data.samples,this.dataType,e,0,this.data.samples.length),this.fromExisting_(this.fmt.numChannels,this.fmt.sampleRate,"8m",mulaw_encode(e),{container:this.correctContainer_()})}fromMuLaw(e="16"){this.fromExisting_(this.fmt.numChannels,this.fmt.sampleRate,"16",mulaw_decode(this.data.samples),{container:this.correctContainer_()}),"16"!=e&&this.toBitDepth(e)}toBitDepth(e,t=!0){let i=e,r=this.bitDepth;t||("32f"!=e&&(i=this.dataType.bits.toString()),r=""+this.dataType.bits),this.assureUncompressed_();var s=this.getSamples(!0),t=new Float64Array(s.length);changeBitDepth(s,r,t,i),this.fromExisting_(this.fmt.numChannels,this.fmt.sampleRate,e,t,{container:this.correctContainer_()})}toSampleRate(t,i){this.validateResample_(t);var r=this.getSamples();let s=[];if(r.constructor===Float64Array)s=resample(r,this.fmt.sampleRate,t,i);else for(let e=0;e<r.length;e++)s.push(resample(r[e],this.fmt.sampleRate,t,i));this.fromExisting_(this.fmt.numChannels,t,this.bitDepth,s,{container:this.correctContainer_()})}validateResample_(e){if(!validateSampleRate(this.fmt.numChannels,this.fmt.bitsPerSample,e))throw new Error("Invalid sample rate.");if(-1<["4","8a","8m"].indexOf(this.bitDepth))throw new Error("wavefile can't change the sample rate of compressed files.")}assure16Bit_(){this.assureUncompressed_(),"16"!=this.bitDepth&&this.toBitDepth("16")}assureUncompressed_(){"8a"==this.bitDepth?this.fromALaw():"8m"==this.bitDepth?this.fromMuLaw():"4"==this.bitDepth&&this.fromIMAADPCM()}correctContainer_(){return"RF64"==this.container?"RIFF":this.container}fromExisting_(e,t,i,r,s){var a=new WaveFileCueEditor;Object.assign(this.fmt,a.fmt),Object.assign(this.fact,a.fact),Object.assign(this.ds64,a.ds64),Object.assign(this.data,a.data),this.newWavFile_(e,t,i,r,s)}}function outputSize_(e,t){let i=e/t;return i%2&&i++,i}class WaveFile extends WaveFileConverter{constructor(e){super(),e&&this.fromBuffer(e)}fromBase64(e){this.fromBuffer(decode(e))}toBase64(){return encode(this.toBuffer())}toDataURI(){return"data:audio/wav;base64,"+this.toBase64()}fromDataURI(e){this.fromBase64(e.replace("data:audio/wav;base64,",""))}}class WavFile{constructor(e){e instanceof Uint8Array?this.fromRawData(e):e instanceof VirtualFile&&this.fromVirtualFile(e)}fromRawData(e){return this.rawData=e,this}fromVirtualFile(e){e=e.stream;return this.rawData=new Uint8Array(e.buffer,e.byteOffset,e.byteLength),this}getRawData(){return this.rawData}getData(){if(!this.decodedData){if(!this.rawData)throw new Error("No data loaded");this.decodedData=this.decodeData(this.rawData),this.rawData=void 0}return this.decodedData}setData(e){this.rawData=void 0,this.decodedData=e}decodeData(e){let t=new WaveFile(e);return"4"===t.bitDepth&&t.fromIMAADPCM(),t.toBuffer()}isRawImaAdpcm(){return this.rawData&&"4"===new WaveFile(this.rawData).bitDepth}}class LazyAsyncResourceCollection{constructor(e,t=!0){this.resourceFactory=e,this.cache=t,this.resources=new Map}setDir(e){this.rfsDir=e}set(e,t){this.resources.set(e,t)}async has(e){return!!this.resources.has(e)||(await this.rfsDir?.containsEntry(e)??!1)}async get(e){let t;return t=this.resources.get(e),!t&&await this.rfsDir?.containsEntry(e)&&(t=await this.resourceFactory(await this.rfsDir.getRawFile(e)),this.cache&&this.resources.set(e,t)),t}clear(){this.resources.clear()}}class Mp3File{constructor(e){this.file=e}asFile(){return new File([this.file],this.file.name,{type:"audio/mp3"})}}const mixDatabase=(new Map).set("cameo.mix",["adogicon.shp","adoguico.shp","aengicon.shp","aenguico.shp","agapgen.shp","agisicon.shp","ahrvicon.shp","ahrvuico.shp","aparicon.shp","apchicon.shp","apcicon.shp","artyicon.shp","asaticon.shp","ayaricon.shp","batricon.shp","beagicon.shp","bggyicon.shp","bolticon.shp","brrkicon.shp","carricon.shp","ccomicon.shp","ccomuico.shp","chemicon.shp","chroicon.shp","clckicon.shp","clegicon.shp","cleguico.shp","clonicon.shp","cnsticon.shp","crryicon.shp","csphicon.shp","darken.shp","desoicon.shp","desouico.shp","desticon.shp","detnicon.shp","dlphicon.shp","dlphuico.shp","dogicon.shp","doguico.shp","dredicon.shp","dronicon.shp","e1icon.shp","e1uico.shp","e2icon.shp","e2uico.shp","e4icon.shp","empicon.shp","engnicon.shp","facticon.shp","falcicon.shp","fixicon.shp","flakicon.shp","flkticon.shp","flktuico.shp","forticon.shp","fsdicon.shp","fspicon.shp","fstdicon.shp","fvicon.shp","fvuico.shp","gapicon.shp","gat2icon.shp","gateicon.shp","gbayicon.shp","gcanicon.shp","giicon.shp","giuico.shp","gorep.shp","gtnkicon.shp","gtnkuico.shp","gwepicon.shp","handicon.shp","harvicon.shp","harvuico.shp","heliicon.shp","hindicon.shp","hmecicon.shp","hovricon.shp","htkicon.shp","htkuico.shp","htnkicon.shp","htnkuico.shp","ioncicon.shp","ircricon.shp","ironicon.shp","ivanicon.shp","ivanuico.shp","ivncicon.shp","ivncuico.shp","jjeticon.shp","jjetuico.shp","landicon.shp","lasricon.shp","liteicon.shp","lpsticon.shp","mcvicon.shp","mcvuico.shp","metricon.shp","mltiicon.shp","mmchicon.shp","msslicon.shp","mtnkicon.shp","mtnkuico.shp","mutcicon.shp","nga2icon.shp","ngaticon.shp","nhpdicon.shp","npsiicon.shp","npwricon.shp","nradicon.shp","nrcticon.shp","nreficon.shp","ntchicon.shp","nukeicon.shp","nwalicon.shp","nwepicon.shp","obliicon.shp","obmbicon.shp","orcaicon.shp","otrnicon.shp","paraicon.shp","pillicon.shp","plticon.shp","plugicon.shp","podsicon.shp","powricon.shp","prisicon.shp","proicon.shp","psicicon.shp","psicuico.shp","psisicon.shp","psiticon.shp","psituico.shp","rad1icon.shp","rad2icon.shp","rad3icon.shp","radricon.shp","rboticon.shp","reficon.shp","rfixicon.shp","rtnkicon.shp","rtnkuico.shp","samicon.shp","sapcicon.shp","sapicon.shp","sbagicon.shp","sealicon.shp","sealuico.shp","seekicon.shp","shadicon.shp","shaduico.shp","shkicon.shp","shkuico.shp","smchicon.shp","smcvicon.shp","smcvuico.shp","snipicon.shp","snipuico.shp","soniicon.shp","spoticon.shp","spyicon.shp","spyuico.shp","sqdicon.shp","sreficon.shp","srefuico.shp","stnkicon.shp","subicon.shp","subticon.shp","tanyicon.shp","tanyuico.shp","techicon.shp","tempicon.shp","teslaicon.shp","tickicon.shp","tnkdicon.shp","tnkduico.shp","towricon.shp","trkaicon.shp","trsticon.shp","trstuico.shp","tslaicon.shp","ttnkicon.shp","ttnkuico.shp","turbicon.shp","twr1icon.shp","twr2icon.shp","twr3icon.shp","v3icon.shp","v3uico.shp","wallicon.shp","weapicon.shp","weaticon.shp","weedicon.shp","wethicon.shp","xxicon.shp","yardicon.shp","yuriicon.shp","yuriuico.shp","yurpicon.shp","yurpuico.shp","zepicon.shp","zepuico.shp"]).set("theme.mix",["200meter.wav","blowitup.wav","burn.wav","destroy.wav","eaglehun.wav","fortific.wav","grinder.wav","hm2.wav","indeep.wav","industro.wav","jank.wav","motorize.wav","power.wav","ra2-opt.wav","ra2-sco.wav","tension.wav"]).set("thememd.mix",["brainfre.wav","bully.wav","deceiver.wav","defend.wav","drok.wav","optionx.wav","phatatta.wav","scorex.wav","tactics.wav","trancelv.wav"]);let sidecResources=["addon.shp","bkgdlg.shp","bkgdmd.shp","bkgdsm.shp","bttnbkgd.shp","button00.shp","button01.shp","button02.shp","button03.shp","button04.shp","button05.shp","button06.shp","button07.shp","button08.shp","button09.shp","button10.shp","button11.shp","credits.shp","diplobtn.shp","gclock2.shp","key.ini","lendcap.shp","lspacer.shp","optbtn.shp","pbeacon.shp","power.shp","powerp.shp","pwrlvl.shp","radar.shp","radar01.shp","radar02.shp","r-dn.shp","rdrbeacn.shp","rendcap.shp","repair.shp","r-up.shp","sell.shp","side1.shp","side2.shp","side2b.shp","side3.shp","sidebar.pal","sidebttn.shp","tab00.shp","tab01.shp","tab02.shp","tab03.shp","tabs.shp","top.shp","uibkgd.pal","wayp.shp"];mixDatabase.set("sidec01.mix",sidecResources).set("sidec02.mix",sidecResources);let sideccdResources=["reportbug.shp"];mixDatabase.set("sidec01cd.mix",sideccdResources).set("sidec02cd.mix",sideccdResources),function(e){e[e.Archive=0]="Archive",e[e.Cdn=1]="Cdn",e[e.Local=2]="Local"}(GameResSource=GameResSource||{});class MpDialogSettings{readIni(e){return this.minMoney=e.getNumber("MinMoney"),this.money=e.getNumber("Money"),this.maxMoney=e.getNumber("MaxMoney"),this.moneyIncrement=e.getNumber("MoneyIncrement"),this.minUnitCount=e.getNumber("MinUnitCount"),this.unitCount=e.getNumber("UnitCount"),this.maxUnitCount=e.getNumber("MaxUnitCount"),this.crates=e.getBool("Crates"),this.gameSpeed=e.getNumber("GameSpeed"),this.mcvRedeploys=e.getBool("MCVRedeploys"),this.shortGame=e.getBool("ShortGame"),this.superWeapons=e.getBool("SuperWeapons"),this.techLevel=e.getNumber("TechLevel"),this.alliesAllowed=e.getBool("AlliesAllowed",!0),this.allyChangeAllowed=e.getBool("AllyChangeAllowed",!0),this.mustAlly=e.getBool("MustAlly"),this.bridgeDestruction=e.getBool("BridgeDestruction",!0),this.multiEngineer=e.getBool("MultiEngineer"),this}}!function(e){e[e.Battle=0]="Battle",e[e.ManBattle=1]="ManBattle",e[e.FreeForAll=2]="FreeForAll",e[e.Unholy=3]="Unholy",e[e.Cooperative=4]="Cooperative"}(GameModeType=GameModeType||{});class GameModes{constructor(e,t){this.modeIniLoader=t,this.entries=new Map,this.loadIni(e)}loadIni(e){e.getOrderedSections().forEach(r=>{let s=GameModeType[r.name]??GameModeType.Battle;[...r.entries.keys()].forEach(e=>{let t=r.getArray(e);if(t.length<5)throw new Error(`Invalid format for mp mode entry "${e}".`);var i=Number(e),e=t[2].toLowerCase(),e={id:i,type:s,label:t[0],description:t[1],rulesOverride:e,mapFilter:t[3],randomMapsAllowed:t[4],aiAllowed:i<3,mpDialogSettings:(new MpDialogSettings).readIni(this.modeIniLoader(e).getOrCreateSection("MultiplayerDialogSettings"))};this.entries.set(i,e)})})}getById(e){if(!this.entries.has(e))throw new Error("No game mode found with id "+e);return this.entries.get(e)}hasId(e){return this.entries.has(e)}getAll(){return[...this.entries.values()]}}class MapManifest{fromIni(t,e){return this.fileName=t.getString("File")||t.name.toLowerCase()+".map",this.uiName=t.getString("Description"),this.maxSlots=t.getNumber("MaxPlayers"),this.official=!0,this.gameModes=e.filter(e=>t.getArray("GameMode").includes(e.mapFilter)),this}getFullMapTitle(e){return this.addTitleSlotsSuffix(e.get(this.uiName),this.maxSlots)}addTitleSlotsSuffix(e,t){return e.match(/(\(|()\s*\d(-\d)?\s*(\)|))\s*$/)||(e+=` (2${2<t?"-"+t:""})`),e}fromMapFile(e,t){var i=e.readAsString();let r=e.filename;const s=new IniFile(this.extractIniSection("Basic",i)).getSection("Basic");if(!s)throw new Error(`Map "${r}" is missing the [Basic] section`);this.fileName=r,this.uiName="NOSTR:"+(s.getString("Name")||r.replace(/\.[^.]+$/,""));i=this.extractIniSection("Waypoints",i);let a=i?new IniFile(i).getSection("Waypoints"):void 0;this.maxSlots=[...a?.entries.keys()??[]].filter(e=>Number(e)<8).length,this.official=s.getBool("Official");let n=s.getArray("GameMode",void 0,["standard"]);return this.gameModes=t.filter(e=>n.includes(e.mapFilter)),this}extractIniSection(t,i){t=i.indexOf(`[${t}]`);if(-1!==t){let e=t+1;for(;e<i.length&&("["!==i[e]||"\n"!==i[e-1]);e++);return i.slice(t,e)}}}class MapList{constructor(e){this.gameModes=e,this.manifests=[]}addFromIni(i){let e=i.getSection("MultiMaps");if(!e)throw new Error("Invalid map list. Missing [MultiMaps] section.");return this.manifests=this.manifests.concat([...e.entries.values()].map(e=>{var t=i.getSection(e);if(!t)throw new Error(`Invalid map list. Missing [${e}] section.`);return(new MapManifest).fromIni(t,this.gameModes.getAll())})),this.dedupeEntries(),this}add(e){this.manifests.push(e)}addFromMapFile(e){this.add((new MapManifest).fromMapFile(e,this.gameModes.getAll()))}getAll(){return this.manifests}getByName(t){return this.manifests.find(e=>e.fileName.toLowerCase()===t.toLowerCase())}sortByName(){this.manifests.sort((e,t)=>e.fileName.localeCompare(t.fileName))}clone(){let e=new MapList(this.gameModes);return e.manifests=[...this.manifests],e}mergeWith(e){return this.manifests.push(...e.manifests),this.dedupeEntries(),this}dedupeEntries(){this.manifests=[...new Map(this.manifests.map(e=>[e.fileName.toLowerCase(),e])).values()]}}class Section_Section{getMatrix(e){return this.matrices[e]}}var MixinRulesType,_a,ObjectType,HvaFile_THREE=__webpack_require__(70);class HvaFile{constructor(e){e instanceof VirtualFile&&this.fromVirtualFile(e)}fromVirtualFile(e){this.filename=e.filename;let i=e.stream;this.sections=[],i.readCString(16);var r=i.readInt32(),s=i.readInt32();for(let e=0;e<s;++e){let e=new Section_Section;e.name=i.readCString(16),e.matrices=new Array(r),this.sections.push(e)}for(let t=0;t<r;++t)for(let e=0;e<s;++e)this.sections[e].matrices[t]=this.readMatrix(i)}readMatrix(t){let i=[];for(let e=0;e<3;++e)i.push(t.readFloat32(),t.readFloat32(),t.readFloat32(),t.readFloat32());return i.push(0,0,0,1),(new HvaFile_THREE.Matrix4).fromArray(i).transpose()}}!function(e){e[e.NoDogEngiKills=0]="NoDogEngiKills"}(MixinRulesType=MixinRulesType||{});class Engine{static getVersion(){return version.split(".").slice(0,2).join(".")}static getModHash(){if(!this.modHash)throw new Error("Rules must be loaded first");return this.modHash}static getActiveMod(){return this.activeMod}static setActiveMod(e){this.activeMod=e}static initGameResSource(e){this.gameResSource=e}static async initRfs(e){let t=this.rfs=new RealFileSystem;return t.addRootDirectoryHandle(e),t}static async initVfs(e,t){return this.vfs=new VirtualFileSystem(e,t),_a.iniFiles.setVfs(this.vfs),_a.palettes.setVfs(this.vfs),_a.images.setVfs(this.vfs),_a.voxels.setVfs(this.vfs),_a.voxelAnims.setVfs(this.vfs),_a.tileData.setVfs(this.vfs),_a.sounds.setVfs(this.vfs),_a.themes.setDir(await this.rfs?.findDirectory(_a.rfsSettings.musicDir)),_a.taunts.setDir(await this.rfs?.findDirectory(_a.rfsSettings.tauntsDir)),this.vfs}static supportsTheater(t){var e=this.getActiveEngine();return this.theaterSettings.get(e)?.some(e=>e.type===t)||!1}static getTheaterSettings(e,t){if(!this.theaterSettings.has(e))throw new Error('Unknown engineType "'+e);e=this.theaterSettings.get(e).find(e=>e.type===t);if(!e)throw new Error(`Unsupported theater "${TheaterType[t]}"`);return e}static async loadTheater(e){if(!_a.rules||!_a.art)throw new Error("Rules and art should be loaded first");if(void 0===_a.gameResSource)throw new Error("No gameResSource is set");var t=_a.getActiveEngine();let i;var r,s=_a.getTheaterSettings(t,e);if(_a.gameResSource!==GameResSource.Cdn)for(var a of s.mixes)await _a.vfs.addMixFile(a);return _a.theaters.has(e)?i=_a.theaters.get(e):(r=_a.getTheaterIni(t,e),t=_a.getTileData(),i=Theater.factory(e,r,s,t,_a.palettes),_a.theaters.set(e,i)),_a.activeTheater=i,i}static unloadTheater(e){if(_a.vfs){var t,i=_a.getActiveEngine();for(t of _a.getTheaterSettings(i,e).mixes)_a.vfs.removeArchive(t)}}static unloadSideMixData(){for(var e of["sidec01.mix","sidec01cd.mix"]){var t,i=mixDatabase.get(e);if(!i)return void console.warn(`Mix "${e}" not found in mix database`);for(t of i)("pal"===t.split(".").pop()?_a.palettes:_a.images).clear(t)}}static getTheaterIni(e,t){t=_a.getTheaterSettings(e,t).theaterIni;return _a.getIni(t)}static loadRules(){var e=this.getFileNameVariant("rules.ini"),t=this.getFileNameVariant("art.ini"),i=this.getFileNameVariant("ai.ini");let r=this.iniFiles.get(e),s=this.iniFiles.get(t);var a=this.iniFiles.get(i);if(!r)throw new Error(`Rules "${e}" not found`);if(!s)throw new Error(`Art "${t}" not found`);if(!a)throw new Error(`AI "${i}" not found`);t=this.iniFiles.get(_a.customRulesFileName),i=this.iniFiles.get(_a.customArtFileName);if(!t)throw new Error(`Rules "${_a.customRulesFileName}" not found`);if(!i)throw new Error(`Art "${_a.customArtFileName}" not found`);_a.art=s.clone().mergeWith(i),_a.rules=_a.patchAudioVisualRules(r.clone().mergeWith(t)),_a.ai=a,_a.modHash=_a.computeModHash()}static patchAudioVisualRules(i){if(this.activeEngine===EngineType.YurisRevenge){let t=i.getSection("General");if(t){let e=i.getSection("AudioVisual");var r;for(r of["DamageFireTypes","OreTwinkle","BarrelExplode","BarrelDebris","BarrelParticle","NukeTakeOff","Wake","DropPod","DeadBodies","MetallicDebris","BridgeExplosions","IonBlast","IonBeam","WeatherConClouds","WeatherConBolts","WeatherConBoltExplosion","DominatorWarhead","DominatorDamage","DominatorCaptureRange","DominatorFirstAnim","DominatorSecondAnim","DominatorFireAtPercentage","ChronoPlacement","ChronoBeam","ChronoBlast","ChronoBlastDest","WarpIn","WarpOut","WarpAway","IronCurtainInvokeAnim","ForceShieldInvokeAnim","WeaponNullifyAnim","ChronoSparkle1","InfantryExplode","FlamingInfantry","InfantryHeadPop","InfantryNuked","InfantryVirus","InfantryBrute","InfantryMutate","Behind","MoveFlash","Parachute","BombParachute","DropZoneAnim","EMPulseSparkles"])e?.set(r,t.getString(r))}}return i}static computeModHash(){if(!this.vfs)throw new Error("VFS not initialized");let e=[this.customRulesFileName,this.customArtFileName,this.customMpModesFileName,this.shroudFileName,this.getFileNameVariant("rules.ini"),this.getFileNameVariant("art.ini"),this.getFileNameVariant("ai.ini"),..._a.mixinRulesFileNames.values()];var t,i,r,s=this.theaterSettings.get(this.getActiveEngine());if(!s)throw new Error('Unsupported engineType "'+this.getActiveEngine());for(t of s)e.push(t.theaterIni);let a=this.getMpModes();for(i of a.getAll())e.push(i.rulesOverride);let n=new Crc32;for(r of e){if(!this.vfs.fileExists(r))throw new Error(`File ${r} not found`);var o=this.vfs.openFile(r).stream;n.append(new Uint8Array(o.buffer,o.byteOffset,o.byteLength))}return n.append(binaryStringToUint8Array(this.getVersion())),n.get()}static getRules(){if(!_a.rules)throw new Error("Rules must be loaded first");return _a.rules}static getArt(){if(!_a.art)throw new Error("Art must be loaded first");return _a.art}static getAi(){if(!_a.ai)throw new Error("AI must be loaded first");return _a.ai}static getFileNameVariant(e){var t=this.getActiveEngine();let i;if(t===EngineType.YurisRevenge)i="md";else{if(t!==EngineType.RedAlert2)throw new Error("Unsupported engine type "+EngineType[t]);i=""}return i?e.replace(/\.([^.]+)$/,i+".$1"):e}static getMpModes(){return new GameModes(this.getIni(this.customMpModesFileName),e=>this.getIni(e))}static getUiIni(){var e=this.getFileNameVariant("ui.ini");return this.getIni(e)}static getIni(e){if(!this.iniFiles.has(e))throw new Error(`INI file ${e} not found.`);return this.iniFiles.get(e)}static async loadMapList(){if(!this.vfs)throw new Error("File system not initialized");var e,i,r,t=this.getMpModes();let s=new MapList(t);s.addFromIni(this.getIni(this.getFileNameVariant("missions.pkt")));for(e of this.vfs.listArchives()){var a=e.toLowerCase().replace(/\.[^.]+$/,"")+".pkt";this.vfs.fileExists(a)&&s.addFromIni(new IniFile(this.vfs.openFile(a)))}let n=new MapList(t),o=this.supportedMapTypes.get(this.getActiveEngine());if(!o)throw new Error(`No map types defined for engine type "${_a.getActiveEngine()}"`);if(this.rfs)for await(var l of this.rfs.getEntries()){let t=l.toLowerCase();try{t.endsWith(".pkt")?(i=new IniFile(await this.rfs.openFile(l,!0)),s.addFromIni(i)):o.some(e=>t.endsWith("."+e))&&(r=await this.rfs.openFile(l,!0),n.addFromMapFile(r))}catch(e){console.warn(`Couldn't read file "${l}"`,e)}}return n.sortByName(),s.mergeWith(n),this.mapList=s,s}static getTileData(){return _a.tileData}static getImages(){return _a.images}static getVoxels(){return _a.voxels}static getVoxelAnims(){return _a.voxelAnims}static getPalettes(){return _a.palettes}static getSounds(){return _a.sounds}static getThemes(){return _a.themes}static getTaunts(){return _a.taunts}static getActiveEngine(){if(!this.activeEngine)throw new Error("Engine type not initialized");return this.activeEngine}static setActiveEngine(e){this.activeEngine=e}static getLastTheaterType(){return _a.activeTheater?.type}static getCacheDir(){try{return this.getOrCreateDir(this.rfsSettings.cacheDir,!0)}catch(e){return void console.error("Couldn't get cache directory",[e])}}static async getReplayDir(){var i=this.getActiveMod();if(i){let e=await this.getModDir(),t=await e?.getDirectory(i);return t?.getOrCreateDirectory(_a.rfsSettings.replayDir)}return this.getOrCreateDir(this.rfsSettings.replayDir)}static getModDir(){return this.getOrCreateDir(_a.rfsSettings.modDir)}static getMapDir(){return this.getOrCreateDir(_a.rfsSettings.mapDir)}static async getOrCreateDir(e,t=!1){let i=this.rfs?.getRootDirectory();if(i)return await i.getOrCreateDirectory(e,t)}static getMapList(){return this.mapList}static destroy(){this.activeEngine=void 0,this.activeTheater=void 0,this.activeMod=void 0,this.modHash=void 0,this.mapList=void 0,this.rfs=void 0,this.vfs=void 0,this.art=void 0,this.iniFiles.clear(),this.images.clear(),this.palettes.clear(),this.rules=void 0,this.ai=void 0,this.theaters.clear(),this.tileData.clear(),this.voxels.clear(),this.voxelAnims.clear()}}_a=Engine,Engine.UI_ANIM_SPEED=2,Engine.rfsSettings={menuVideoFileName:"ra2ts_l.webm",splashImgFileName:"glsl.png",mapDir:"maps",modDir:"mods",musicDir:"music",tauntsDir:"Taunts",cacheDir:"cache",replayDir:"replays"},Engine.supportedMapTypes=new Map([[EngineType.RedAlert2,["mpr","map"]],[EngineType.YurisRevenge,["mpr","map","yrm"]]]),Engine.images=new LazyResourceCollection(e=>new ShpFile(e)),Engine.voxels=new LazyResourceCollection(e=>new VxlFile(e)),Engine.voxelAnims=new LazyResourceCollection(e=>new HvaFile(e)),Engine.sounds=new LazyResourceCollection(e=>new WavFile(e)),Engine.themes=new LazyAsyncResourceCollection(e=>new Mp3File(e),!1),Engine.taunts=new LazyAsyncResourceCollection(async e=>new WavFile(new Uint8Array(await e.arrayBuffer()))),Engine.iniFiles=new LazyResourceCollection(e=>new IniFile(e)),Engine.tileData=new LazyResourceCollection(e=>new TmpFile(e)),Engine.palettes=new LazyResourceCollection(e=>new Palette(e)),Engine.theaters=new Map,Engine.theaterSettings=(new Map).set(EngineType.RedAlert2,[{type:TheaterType.Temperate,theaterIni:"temperat.ini",mixes:["isotemp.mix","temperat.mix","tem.mix"],extension:".tem",newTheaterChar:"T",isoPaletteName:"isotem.pal",unitPaletteName:"unittem.pal",overlayPaletteName:"temperat.pal",libPaletteName:"libtem.pal"},{type:TheaterType.Snow,theaterIni:"snow.ini",mixes:["isosnow.mix","snow.mix","sno.mix"],extension:".sno",newTheaterChar:"A",isoPaletteName:"isosno.pal",unitPaletteName:"unitsno.pal",overlayPaletteName:"snow.pal",libPaletteName:"libsno.pal"},{type:TheaterType.Urban,theaterIni:"urban.ini",mixes:["isourb.mix","urb.mix","urban.mix"],extension:".urb",newTheaterChar:"U",isoPaletteName:"isourb.pal",unitPaletteName:"uniturb.pal",overlayPaletteName:"urban.pal",libPaletteName:"liburb.pal"}]).set(EngineType.YurisRevenge,[{type:TheaterType.Temperate,theaterIni:"temperatmd.ini",mixes:["isotemp.mix","isotemmd.mix","temperat.mix","tem.mix"],extension:".tem",newTheaterChar:"T",isoPaletteName:"isotem.pal",unitPaletteName:"unittem.pal",overlayPaletteName:"temperat.pal",libPaletteName:"libtem.pal"},{type:TheaterType.Snow,theaterIni:"snowmd.ini",mixes:["isosnomd.mix","snowmd.mix","isosnow.mix","snow.mix","sno.mix"],extension:".sno",newTheaterChar:"A",isoPaletteName:"isosno.pal",unitPaletteName:"unitsno.pal",overlayPaletteName:"snow.pal",libPaletteName:"libsno.pal"},{type:TheaterType.Urban,theaterIni:"urbanmd.ini",mixes:["isourbmd.mix","isourb.mix","urb.mix","urban.mix"],extension:".urb",newTheaterChar:"U",isoPaletteName:"isourb.pal",unitPaletteName:"uniturb.pal",overlayPaletteName:"urban.pal",libPaletteName:"liburb.pal"},{type:TheaterType.NewUrban,theaterIni:"urbannmd.ini",mixes:["isoubnmd.mix","isoubn.mix","ubn.mix","urbann.mix"],extension:".ubn",newTheaterChar:"N",isoPaletteName:"isoubn.pal",unitPaletteName:"unitubn.pal",overlayPaletteName:"urbann.pal",libPaletteName:"libubn.pal"},{type:TheaterType.Desert,theaterIni:"desertmd.ini",mixes:["isodesmd.mix","desert.mix","des.mix","isodes.mix"],extension:".des",newTheaterChar:"D",isoPaletteName:"isodes.pal",unitPaletteName:"unitdes.pal",overlayPaletteName:"desert.pal",libPaletteName:"libdes.pal"},{type:TheaterType.Lunar,theaterIni:"lunarmd.ini",mixes:["isolunmd.mix","isolun.mix","lun.mix","lunar.mix"],extension:".lun",newTheaterChar:"L",isoPaletteName:"isolun.pal",unitPaletteName:"unitlun.pal",overlayPaletteName:"lunar.pal",libPaletteName:"liblun.pal"}]),Engine.customRulesFileName="rulescd.ini",Engine.customArtFileName="artcd.ini",Engine.customMpModesFileName="mpmodescd.ini",Engine.shroudFileName="shroud.shp",Engine.mixinRulesFileNames=(new Map).set(MixinRulesType.NoDogEngiKills,"nodogengikills.ini"),function(e){e[e.None=0]="None",e[e.Aircraft=1]="Aircraft",e[e.Building=2]="Building",e[e.Infantry=3]="Infantry",e[e.Overlay=4]="Overlay",e[e.Smudge=5]="Smudge",e[e.Terrain=6]="Terrain",e[e.Vehicle=7]="Vehicle",e[e.Animation=8]="Animation",e[e.Projectile=9]="Projectile",e[e.VoxelAnim=10]="VoxelAnim",e[e.Debris=11]="Debris"}(ObjectType=ObjectType||{});class MapObject{constructor(e){this.type=e}isStructure(){return this.type===ObjectType.Building}isVehicle(){return this.type===ObjectType.Vehicle}isInfantry(){return this.type===ObjectType.Infantry}isAircraft(){return this.type===ObjectType.Aircraft}isTerrain(){return this.type===ObjectType.Terrain}isSmudge(){return this.type===ObjectType.Smudge}isOverlay(){return this.type===ObjectType.Overlay}isNamed(){return"name"in this}isTechno(){return"health"in this}}class NamedMapObject extends MapObject{}class Techno extends NamedMapObject{}class Structure extends Techno{constructor(){super(ObjectType.Building)}}class Vehicle extends Techno{constructor(){super(ObjectType.Vehicle)}}class Infantry extends Techno{constructor(){super(ObjectType.Infantry)}}class Aircraft extends Techno{constructor(){super(ObjectType.Aircraft)}}class Terrain extends NamedMapObject{constructor(){super(ObjectType.Terrain)}}class Smudge extends NamedMapObject{constructor(){super(ObjectType.Smudge)}}class Overlay extends MapObject{constructor(){super(ObjectType.Overlay)}}class Format80{static decode(e,t){t=new Uint8Array(t);return this.decodeInto(e,t),t}static decodeInto(e,t){let i=new DataStream(new DataView(e.buffer,e.byteOffset,e.byteLength)),r=0;for(;;){var s=i.readUint8();if(0==(128&s)){var a=i.readUint8(),n=3+((112&s)>>4);this.replicatePrevious(t,r,r-(((15&s)<<8)+a),n),r+=n}else if(0==(64&s)){n=63&s;if(0==n)return r;t.set(i.readUint8Array(n),r),r+=n}else{s=63&s;if(62==s)for(var o=i.readInt16(),l=i.readUint8(),h=r+o;r<h;r++)t[r]=l;else if(63==s){o=i.readInt16();let e=i.readInt16();if(e>=r)throw new Error(`srcIndex >= destIndex ${e} `+r);for(var c=r+o;r<c;r++)t[r]=t[e++]}else{s=3+s;let e=i.readInt16();if(e>=r)throw new Error(`srcIndex >= destIndex ${e} `+r);for(var u=r+s;r<u;r++)t[r]=t[e++]}}}}static replicatePrevious(t,i,r,s){if(i<r)throw new Error(`srcIndex > destIndex ${r} `+i);if(i-r==1)for(let e=0;e<s;e++)t[i+e]=t[i-1];else for(let e=0;e<s;e++)t[i+e]=t[r+e]}}var PixelFormat,TagRepeatType,TriggerEventType,TriggerActionType,SideType,RadarEventType,PrereqCategory,TerrainType,LandType,SpeedType,InfDeathType,PipColor,LocomotorType,MovementZone,ArmorType,LandTargeting,NavalTargeting,WeaponType,VeteranAbility,VhpScan,BuildCat,FactoryType,OccupationBits,SuperWeaponType,EventType,ZoneType,AiDifficulty,PowerupType,NotifyTick,NotifyWarpChange,SuperWeaponStatus,EffectStatus,NotifyPower,NotifySuperWeaponActivate,StanceType,TaskStatus,lzo1x=__webpack_require__(887).default;class MiniLzo{static decompress(e,t){e={inputBuffer:e,outputBuffer:null},t=lzo1x.decompress(e,{outputSize:t});if(0!==t)throw new Error("MiniLzo decode failed with code "+t);return e.outputBuffer}}class Format5{static decode(e,t,i=5){t=new Uint8Array(t);return this.decodeInto(e,t,i),t}static decodeInto(e,i,r=5){var t=i.length;let s=0,a=0;for(;a<t;){var n=e[s+1]<<8|e[s];s+=2;var o=e[s+1]<<8|e[s];if(s+=2,!n||!o)break;let t;t=80===r?Format80.decode(e.subarray(s,s+n),o):MiniLzo.decompress(e.subarray(s,s+n),o);for(let e=0;e<o;++e)i[a+e]=t[e];s+=n,a+=o}}}function getChannelCount(e){switch(e){case PixelFormat.Indexed:return 1;case PixelFormat.Rgb:return 3;case PixelFormat.Rgba:return 4;default:throw new Error("Unsupported pixel format "+e)}}!function(e){e[e.Rgb=1]="Rgb",e[e.Rgba=2]="Rgba",e[e.Indexed=3]="Indexed"}(PixelFormat=PixelFormat||{});class Bitmap{constructor(e,t,i,r=PixelFormat.Rgba){var s=getChannelCount(r);this.data=i||new Uint8Array(s*e*t),this.pixelFormat=r,this.width=e,this.height=t}drawIndexedImage(t,e,i){var r=getChannelCount(this.pixelFormat);const s=this.data;var a=this.width,n=r*a,o=r*a*this.height;let l=0+n*i+r*e,h=0;for(let e=0;e<t.height;e++){for(let e=0;e<t.width;e++){var c=t.data[h];0!==c&&0<=l&&l<o&&(s[l]=c,3<=r&&(s[l+1]=0,s[l+2]=0),4===r&&(s[l+3]=255)),l+=r,h++}l+=n-t.width*r}}}class IndexedBitmap extends Bitmap{constructor(e,t,i){super(e,t,i,PixelFormat.Indexed)}}class RgbBitmap extends Bitmap{constructor(e,t,i){super(e,t,i,PixelFormat.Rgb)}}class RgbaBitmap extends Bitmap{constructor(e,t,i){super(e,t,i,PixelFormat.Rgba)}drawRgbaImage(t,e,i){const r=this.data;var s=this.width,a=4*s,n=4*s*this.height;let o=0+a*i+4*e,l=0;for(let e=0;e<t.height;e++){for(let e=0;e<t.width;e++)0<=o&&o<n&&(r[o]=t.data[l],r[o+1]=t.data[l+1],r[o+2]=t.data[l+2],r[o+3]=t.data[l+3]),o+=4,l+=4;o+=a-4*t.width}}}!function(e){e[e.OnceAny=0]="OnceAny",e[e.OnceAll=1]="OnceAll",e[e.Repeat=2]="Repeat"}(TagRepeatType=TagRepeatType||{});class TagsReader{read(e){let t=[];for(var[i,r]of e.entries){var s=r.split(",");s.length<3?console.warn(`Invalid tag ${i}=${r}. Skipping.`):(r=Number(s[0]),void 0!==TagRepeatType[r]?(s={id:i,repeatType:r,name:s[1],triggerId:s[2]},t.push(s)):console.warn(`Invalid repeat value ${r} for tag id ${i}. Skipping.`))}return t}}!function(e){e[e.NoEvent=0]="NoEvent",e[e.EnteredBy=1]="EnteredBy",e[e.SpiedBy=2]="SpiedBy",e[e.AttackedByAny=6]="AttackedByAny",e[e.DestroyedByAny=7]="DestroyedByAny",e[e.AnyEvent=8]="AnyEvent",e[e.DestroyedAllUnits=9]="DestroyedAllUnits",e[e.DestroyedAllBuildings=10]="DestroyedAllBuildings",e[e.DestroyedAll=11]="DestroyedAll",e[e.CreditsExceed=12]="CreditsExceed",e[e.ElapsedTime=13]="ElapsedTime",e[e.MissionTimerExpired=14]="MissionTimerExpired",e[e.DestroyedBuildings=15]="DestroyedBuildings",e[e.DestroyedUnits=16]="DestroyedUnits",e[e.NoFactoriesLeft=17]="NoFactoriesLeft",e[e.BuildBuilding=19]="BuildBuilding",e[e.BuildUnit=20]="BuildUnit",e[e.BuildInfantry=21]="BuildInfantry",e[e.BuildAircraft=22]="BuildAircraft",e[e.CrossesHorizontalLine=25]="CrossesHorizontalLine",e[e.CrossesVerticalLine=26]="CrossesVerticalLine",e[e.GlobalIsSet=27]="GlobalIsSet",e[e.GlobalIsCleared=28]="GlobalIsCleared",e[e.DestroyedOrCaptured=29]="DestroyedOrCaptured",e[e.LowPower=30]="LowPower",e[e.DestroyedBridge=31]="DestroyedBridge",e[e.BuildingExists=32]="BuildingExists",e[e.ComesNearWaypoint=34]="ComesNearWaypoint",e[e.LocalIsSet=36]="LocalIsSet",e[e.LocalIsCleared=37]="LocalIsCleared",e[e.FirstDamagedCombat=38]="FirstDamagedCombat",e[e.HalfHealthCombat=39]="HalfHealthCombat",e[e.QuarterHealthCombat=40]="QuarterHealthCombat",e[e.FirstDamagedAny=41]="FirstDamagedAny",e[e.HalfHealthAny=42]="HalfHealthAny",e[e.QuarterHealthAny=43]="QuarterHealthAny",e[e.AttackedByHouse=44]="AttackedByHouse",e[e.AmbientLightBelow=45]="AmbientLightBelow",e[e.AmbientLightAbove=46]="AmbientLightAbove",e[e.ElapsedScenarioTime=47]="ElapsedScenarioTime",e[e.DestroyedOrCapturedOrInfiltrated=48]="DestroyedOrCapturedOrInfiltrated",e[e.PickupCrate=49]="PickupCrate",e[e.PickupCrateAny=50]="PickupCrateAny",e[e.RandomDelay=51]="RandomDelay",e[e.CreditsBelow=52]="CreditsBelow",e[e.SpyEnteringAsHouse=53]="SpyEnteringAsHouse",e[e.SpyEnteringAsInfantry=54]="SpyEnteringAsInfantry",e[e.DestroyedAllUnitsNaval=55]="DestroyedAllUnitsNaval",e[e.DestroyedAllUnitsLand=56]="DestroyedAllUnitsLand",e[e.BuildingNotExists=57]="BuildingNotExists"}(TriggerEventType=TriggerEventType||{}),function(e){e[e.NoAction=0]="NoAction",e[e.FireSale=9]="FireSale",e[e.TextTrigger=11]="TextTrigger",e[e.DestroyTrigger=12]="DestroyTrigger",e[e.ChangeHouse=14]="ChangeHouse",e[e.RevealMap=16]="RevealMap",e[e.RevealAroundWaypoint=17]="RevealAroundWaypoint",e[e.PlaySoundFx=19]="PlaySoundFx",e[e.PlaySpeech=21]="PlaySpeech",e[e.ForceTrigger=22]="ForceTrigger",e[e.TimerStart=23]="TimerStart",e[e.TimerStop=24]="TimerStop",e[e.TimerExtend=25]="TimerExtend",e[e.TimerShorten=26]="TimerShorten",e[e.TimerSet=27]="TimerSet",e[e.GlobalSet=28]="GlobalSet",e[e.GlobalClear=29]="GlobalClear",e[e.DestroyObject=32]="DestroyObject",e[e.AddOneTimeSuperWeapon=33]="AddOneTimeSuperWeapon",e[e.AddRepeatingSuperWeapon=34]="AddRepeatingSuperWeapon",e[e.AllChangeHouse=36]="AllChangeHouse",e[e.ResizePlayerView=40]="ResizePlayerView",e[e.PlayAnimAt=41]="PlayAnimAt",e[e.DetonateWarhead=42]="DetonateWarhead",e[e.ReshroudMap=51]="ReshroudMap",e[e.EnableTrigger=53]="EnableTrigger",e[e.DisableTrigger=54]="DisableTrigger",e[e.CreateRadarEvent=55]="CreateRadarEvent",e[e.LocalSet=56]="LocalSet",e[e.LocalClear=57]="LocalClear",e[e.SellBuilding=60]="SellBuilding",e[e.TurnOffBuilding=61]="TurnOffBuilding",e[e.TurnOnBuilding=62]="TurnOnBuilding",e[e.ApplyOneHundredDamage=63]="ApplyOneHundredDamage",e[e.ForceEnd=69]="ForceEnd",e[e.DestroyTag=70]="DestroyTag",e[e.SetAmbientStep=71]="SetAmbientStep",e[e.SetAmbientRate=72]="SetAmbientRate",e[e.SetAmbientLight=73]="SetAmbientLight",e[e.NukeStrike=95]="NukeStrike",e[e.PlaySoundFxAt=99]="PlaySoundFxAt",e[e.UnrevealAroundWaypoint=101]="UnrevealAroundWaypoint",e[e.LightningStrike=102]="LightningStrike",e[e.TimerText=103]="TimerText",e[e.CreateCrate=108]="CreateCrate",e[e.IronCurtainAt=109]="IronCurtainAt",e[e.EvictOccupiers=111]="EvictOccupiers",e[e.Cheer=113]="Cheer",e[e.StopSoundsAt=116]="StopSoundsAt"}(TriggerActionType=TriggerActionType||{});class TriggerReader{read(e,t,i,r){let s=this.readTriggers(e),{events:a,unknownEventTypes:n}=this.readEvents(t),{actions:o,unknownActionTypes:l}=this.readActions(i),h=[...r.values()],c=new Set(s);for(let t of s.values()){var u=a.get(t.id);u&&t.events.push(...u);u=o.get(t.id);u&&t.actions.push(...u),!t.attachedTriggerId||(u=s.find(e=>e.id===t.attachedTriggerId))&&(t.attachedTrigger=u,c.delete(u))}for(let t of c){var d=h.find(e=>e.triggerId===t.id);if(d){let e=t;for(;e;)e.tag=d,e=e.attachedTrigger}else{let e=t;for(;e;){console.warn(`Trigger ${e.id} has no associated tag or valid root trigger. Skipping.`);var p=s.indexOf(e);-1!==p&&s.splice(p,1),e=e.attachedTrigger}}}return{triggers:s,unknownEventTypes:n,unknownActionTypes:l}}readTriggers(e){let t=[];for(var[i,r]of e.entries){var s=r.split(",");s.length<8?console.warn(`Invalid trigger ${i}=${r}. Skipping.`):(s={id:i,houseName:s[0],attachedTriggerId:"<none>"!==s[1]?s[1]:void 0,attachedTrigger:void 0,name:s[2],disabled:Boolean(Number(s[3])),difficulties:{easy:Boolean(Number(s[4])),medium:Boolean(Number(s[5])),hard:Boolean(Number(s[6]))},events:[],actions:[],tag:void 0},t.push(s))}return t}readEvents(e){let t=new Map,s=new Set;for(var[a,i]of e.entries){let r=i.split(",");if(r.length<4)console.warn(`Invalid event ${a}=${i}. Skipping.`);else{var n=Number(r.shift());let i=[];for(let t=0;t<n;t++){var o=Number(r.shift()),l=Number(r.shift());let e=r.splice(0,2===l?2:1);void 0!==TriggerEventType[o]?(l={triggerId:a,eventIndex:t,type:o,params:[l,...e.map(e=>e||"0")]},i.push(l)):(s.add(o),console.warn(`Unknown event type ${o} for trigger id ${a}. Skipping.`))}t.set(a,i)}}return{events:t,unknownEventTypes:s}}readActions(e){let r=new Map,s=new Set;for(var[a,t]of e.entries){let i=t.split(",");if(i.length<9)console.warn(`Invalid action ${a}=${t}. Skipping.`);else{var n=Number(i.shift());if(i.length<8*n)console.warn(`Invalid action ${a}=${t}. Skipping.`);else{let t=[];for(let e=0;e<n;e++){var o=Number(i.shift()),l=i.splice(0,7);void 0!==TriggerActionType[o]?(l={triggerId:a,index:e,type:o,params:[Number(l[0]||"0"),l[1]||"0",l[2]||"0",l[3]||"0",l[4]||"0",l[5]||"0",l[6]?this.readAZActionParam(l[6]):0]},t.push(l)):(s.add(o),console.warn(`Unknown action type ${o} for trigger id "${a}". Skipping.`))}r.set(a,t)}}}return{actions:r,unknownActionTypes:s}}readAZActionParam(e){var t="Z".charCodeAt(0),i="A".charCodeAt(0),t=t-i+1;return 1<e.length?e.charCodeAt(1)-i+(e.charCodeAt(0)-i+1)*t:e.charCodeAt(0)-i}}class MapLighting{constructor(){this.level=0,this.ambient=1,this.red=1,this.green=1,this.blue=1,this.ground=0,this.forceTint=!1}read(e,t=""){return this.level=e.getNumber(t+"Level",.032),this.ambient=e.getNumber(t+"Ambient",1),this.red=e.getNumber(t+"Red",1),this.green=e.getNumber(t+"Green",1),this.blue=e.getNumber(t+"Blue",1),this.ground=e.getNumber(t+"Ground",0),this}copy(e){return this.level=e.level,this.ambient=e.ambient,this.red=e.red,this.green=e.green,this.blue=e.blue,this.ground=e.ground,this.forceTint=e.forceTint,this}}class CellTagsReader{read(e,t){let i=[];for(var[r,s]of e.entries){r={tagId:s,coords:this.readCoords(Number(r),t)};i.push(r)}return i}readCoords(e,t){t=t<4?128:1e3;return{x:e%t,y:Math.floor(e/t)}}}class Variable{constructor(e,t){this.name=e,this.value=t}clone(){return new Variable(this.name,this.value)}}class SpecialFlags{read(e){return this.initialVeteran=e.getBool("InitialVeteran"),this}}class MapFile extends IniFile{fromString(e){super.fromString(e);let t=this.getSection("Map");if(!t)throw new Error("[Map] section not found");e=t.getNumberArray("Size");if(this.fullSize={x:e[0],y:e[1],width:e[2],height:e[3]},e=t.getNumberArray("LocalSize"),this.localSize={x:e[0],y:e[1],width:e[2],height:e[3]},this.theaterType=t.getEnum("Theater",TheaterType,TheaterType.None,!0),this.theaterType===TheaterType.None)throw new Error(`Unsupported theater type "${t.getString("Theater")}"`);let i=this.getSection("Basic");e=this.iniFormat=i?.getNumber("NewINIFormat")??0;return this.readTiles(),this.readWaypoints(this.getOrCreateSection("Waypoints")),this.readStructures(this.getOrCreateSection("Structures")),this.readVehicles(),this.readInfantries(),this.readAircrafts(),this.readTerrains(this.getOrCreateSection("Terrain")),this.readOverlays(),this.readSmudges(),this.readLighting(),this.readTagsAndTriggers(),this.readCellTags(e),this.readVariableNames(),this.startingLocations=this.readStartingLocations(this.waypoints),this.specialFlags=(new SpecialFlags).read(this.getOrCreateSection("SpecialFlags")),this}fromJson(i){if(i[MapFile.artSectionPrefix]){let{[MapFile.artSectionPrefix]:e,...t}=i;this.artOverrides=new IniFile(e),i=t}return super.fromJson(i)}readStartingLocations(e){let t=[];var i;for(i of e.filter(e=>e.number<8).sort((e,t)=>e.number<t.number?-1:1))t.push({x:i.rx,y:i.ry});return t}readLighting(){var e=this.getOrCreateSection("Lighting");this.lighting=(new MapLighting).read(e),this.ionLighting=(new MapLighting).read(e,"Ion"),this.ionLighting.forceTint=!0}readTagsAndTriggers(){this.tags=(new TagsReader).read(this.getOrCreateSection("Tags"));var e=this.getOrCreateSection("Triggers"),t=this.getOrCreateSection("Events"),i=this.getOrCreateSection("Actions"),{triggers:e,unknownEventTypes:t,unknownActionTypes:i}=(new TriggerReader).read(e,t,i,this.tags);this.triggers=e,this.unknownEventTypes=t,this.unknownActionTypes=i}readCellTags(e){this.cellTags=(new CellTagsReader).read(this.getOrCreateSection("CellTags"),e)}readVariableNames(){var e,t,i=this.getOrCreateSection("VariableNames");let r=new Map;for([e,t]of i.entries){var s,a,n=Number(e);Number.isNaN(n)?console.warn(`Map [VariableNames] contains non-numeric index "${e}". Skipping.`):([s,a]=t.split(","),a=new Variable(s,Boolean(Number(a))),r.set(n,a))}this.variables=r}readTiles(){let e=this.getSection("IsoMapPack5");if(!e)throw new Error("[IsoMapPack5] section not found");var t=base64StringToUint8Array(e.getConcatenatedValues()),i=(2*this.fullSize.width-1)*this.fullSize.height,r=new Uint8Array(11*i+4);Format5.decodeInto(t,r);let s=new DataStream(r.buffer),a=2*this.fullSize.width-1;var n,o,l,h,r=this.fullSize.height,c=(e,t)=>t*a+e;this.tiles=new Array(a*r);for(let e=this.maxTileNum=0;e<i;e++){var u=s.readUint16(),d=s.readUint16(),p=Math.max(0,s.readInt16());this.maxTileNum=Math.max(this.maxTileNum,p),s.readInt16();var g=s.readUint8(),m=s.readUint8();s.readUint8();var y=u-d+this.fullSize.width-1,T=u+d-this.fullSize.width-1;0<=y&&y<2*this.fullSize.width&&0<=T&&T<2*this.fullSize.height&&(g={dx:y,dy:T,rx:u,ry:d,z:m,tileNum:p,subTile:g},this.tiles[c(y,Math.floor(T/2))]=g)}for(let t=0;t<this.fullSize.height;t++)for(let e=0;e<=2*this.fullSize.width-2;e++)this.tiles[c(e,t)]||(n=e,h=(o=2*t+e%2)-(l=(n+o)/2+1)+this.fullSize.width+1,this.tiles[c(e,t)]={dx:n,dy:o,rx:l,ry:h,z:0,tileNum:0,subTile:0})}readWaypoints(e){this.waypoints=[];for(var[t,i]of e.entries){var r;let e;isNaN(r=parseInt(t,10))||isNaN(e=parseInt(i,10))||(t=Math.floor(e/1e3),i=e-1e3*t,this.waypoints.push({number:r,rx:i,ry:t}))}}readStructures(e){this.structures=[];for(var[,t]of e.entries){t=t.split(",");if(!(t.length<=15)){let e=new Structure;e.owner=t[0],e.name=t[1],e.health=Number(t[2]),e.rx=Number(t[3]),e.ry=Number(t[4]),e.tag=this.readTagId(t[6]),e.poweredOn=Boolean(Number(t[9])),this.structures.push(e)}}}readTagId(e){return"none"!==e.toLowerCase()?e:void 0}readVehicles(){this.vehicles=[];let e=this.getSection("Units");if(e)for(var t of e.entries.values()){var i=t.split(",");if(i.length<=11)console.warn(`Invalid Vehicle entry: "${t}"`);else{let e=new Vehicle;e.owner=i[0],e.name=i[1],e.health=Number(i[2]),e.rx=Number(i[3]),e.ry=Number(i[4]),e.direction=Number(i[5]),e.tag=this.readTagId(i[7]),e.veterancy=Number(i[8]),e.onBridge="1"===i[10],this.vehicles.push(e)}}}readInfantries(){this.infantries=[];let e=this.getSection("Infantry");if(e)for(var t of e.entries.values()){var i=t.split(",");let e=new Infantry;i.length<=8?console.warn(`Invalid Infantry entry: "${t}"`):(e.owner=i[0],e.name=i[1],e.health=Number(i[2]),e.rx=Number(i[3]),e.ry=Number(i[4]),e.subCell=Number(i[5]),e.direction=Number(i[7]),e.tag=this.readTagId(i[8]),e.veterancy=Number(i[9]),e.onBridge="1"===i[11],this.infantries.push(e))}}readAircrafts(){this.aircrafts=[];let e=this.getSection("Aircraft");if(e)for(var t of e.entries.values()){t=t.split(",");let e=new Aircraft;e.owner=t[0],e.name=t[1],e.health=Number(t[2]),e.rx=Number(t[3]),e.ry=Number(t[4]),e.direction=Number(t[5]),e.tag=this.readTagId(t[7]),e.veterancy=Number(t[8]),e.onBridge="1"===t[t.length-4],this.aircrafts.push(e)}}readTerrains(e){this.terrains=[];for(var[t,i]of e.entries){t=Number(t);if(!isNaN(t)){let e=new Terrain;e.name=i,e.rx=t%1e3,e.ry=Math.floor(t/1e3),this.terrains.push(e)}}}readOverlays(){this.overlays=[],this.maxOverlayId=0;let t=this.getSection("OverlayPack");if(t){var i=base64StringToUint8Array(t.getConcatenatedValues()),r=new Uint8Array(1<<18);Format5.decodeInto(i,r,80);let e=this.getSection("OverlayDataPack");if(e){var i=base64StringToUint8Array(e.getConcatenatedValues()),s=new Uint8Array(1<<18);Format5.decodeInto(i,s,80);for(let t=0;t<this.fullSize.height;t++)for(let e=2*this.fullSize.width-2;0<=e;e--){var a=e,n=2*t+e%2,o=(a+n)/2+1,l=n-o+this.fullSize.width+1,a=o+512*l,n=r[a];if(255!==n){a=s[a];let e=new Overlay;e.id=n,e.value=a,e.rx=o,e.ry=l,this.overlays.push(e),this.maxOverlayId=Math.max(this.maxOverlayId,n)}}}else console.warn("[OverlayDataPack] section not found. Skipping.")}else console.warn("[Overlay] section not found. Skipping.")}readSmudges(){this.smudges=[];let e=this.getSection("Smudge");if(e)for(var t of e.entries.values()){var i=t.split(",");if(i.length<=2)console.warn(`Invalid Smudge entry: "${t}"`);else{let e=new Smudge;e.name=i[0],e.rx=Number(i[1]),e.ry=Number(i[2]),this.smudges.push(e)}}}decodePreviewImage(){let e=this.getSection("Preview"),t=this.getSection("PreviewPack");if(e&&t){var[,,i,r]=e.getArray("Size").map(e=>Number(e)),s=base64StringToUint8Array(t.getConcatenatedValues()),r=new RgbBitmap(i,r);return Format5.decodeInto(s,r.data),r}}}MapFile.artSectionPrefix="ART",function(e){e[e.GDI=0]="GDI",e[e.Nod=1]="Nod",e[e.ThirdSide=2]="ThirdSide",e[e.Civilian=3]="Civilian",e[e.Mutant=4]="Mutant"}(SideType=SideType||{});const sideMap=(new Map).set("GDI",SideType.GDI).set("Nod",SideType.Nod).set("Civilian",SideType.Civilian).set("Mutant",SideType.Mutant).set("ThirdSide",SideType.ThirdSide),defaultUiTooltips=new Map([["Americans","STT:PlayerSideAmerica"],["Alliance","STT:PlayerSideKorea"],["French","STT:PlayerSideFrance"],["Germans","STT:PlayerSideGermany"],["British","STT:PlayerSideBritain"],["Africans","STT:PlayerSideLibya"],["Arabs","STT:PlayerSideIraq"],["Confederation","STT:PlayerSideCuba"],["Russians","STT:PlayerSideRussia"],["YuriCountry","STT:PlayerSideYuriCountry"]]);class CountryRules{constructor(e){this.id=e}readIni(e){this.name=e.name,this.uiName=e.getString("UIName"),this.uiTooltip=e.getString("UITooltip")||defaultUiTooltips.get(this.name);var t=e.getString("Side");if(!t)throw new Error(`Missing Side for country "${this.name}"`);var i=sideMap.get(t);if(void 0===i)throw new Error(`Unknown side "${t}" for country "${this.name}"`);this.side=i,this.multiplay=e.getBool("Multiplay"),this.multiplayPassive=e.getBool("MultiplayPassive"),this.veteranAircraft=e.getArray("VeteranAircraft"),this.veteranInfantry=e.getArray("VeteranInfantry"),this.veteranUnits=e.getArray("VeteranUnits")}}class ObjectRules{static iniSpeedToLeptonsPerTick(e,t){return Math.min(256,256*e/t)}static iniRotToDegsPerTick(e){return e/256*360}constructor(e,t,i=-1,r){this.type=e,this.ini=t,this.index=i,this.generalRules=r,this.parse()}parse(){this.alphaImage=this.ini.getString("AlphaImage")||void 0,this.alternateArcticArt=this.ini.getBool("AlternateArcticArt"),this.crushable=this.ini.getBool("Crushable",this.type===ObjectType.Infantry),this.crushSound=this.ini.getString("CrushSound")||void 0,this.dontScore=this.ini.getBool("DontScore"),this.insignificant=this.ini.getBool("Insignificant"),this.legalTarget=this.ini.getBool("LegalTarget",!0),this.noShadow=this.ini.getBool("NoShadow"),this.uiName=this.ini.getString("UIName")}get name(){return this.ini.name}get imageName(){let e=this.ini.getString("Image");return e&&"null"!==e||(e=this.name),e}}ObjectRules.IMAGE_NONE="none";class WeaponRules{constructor(e){this.rules=e,this.parse()}parse(){this.ambientDamage=this.rules.getNumber("AmbientDamage"),this.anim=this.rules.getArray("Anim"),this.areaFire=this.rules.getBool("AreaFire"),this.burst=this.rules.getNumber("Burst",1),this.cellRangefinding=this.rules.getBool("CellRangefinding"),this.damage=this.rules.getNumber("Damage"),this.decloakToFire=this.rules.getBool("DecloakToFire",!0),this.fireOnce=this.rules.getBool("FireOnce"),this.isAlternateColor=this.rules.getBool("IsAlternateColor"),this.isElectricBolt=this.rules.getBool("IsElectricBolt"),this.isHouseColor=this.rules.getBool("IsHouseColor"),this.isLaser=this.rules.getBool("IsLaser"),this.isRadBeam=this.rules.getBool("IsRadBeam"),this.isSonic=this.rules.getBool("IsSonic"),this.laserDuration=this.rules.getNumber("LaserDuration"),this.limboLaunch=this.rules.getBool("LimboLaunch"),this.minimumRange=this.rules.getNumber("MinimumRange"),this.name=this.rules.name,this.neverUse=this.rules.getBool("NeverUse"),this.omniFire=this.rules.getBool("OmniFire"),this.projectile=this.rules.getString("Projectile"),this.radLevel=this.rules.getNumber("RadLevel"),this.range=this.rules.getNumber("Range"),-2===this.range&&(this.range=Number.POSITIVE_INFINITY),this.report=this.rules.getArray("Report"),this.revealOnFire=this.rules.getBool("RevealOnFire",!0),this.rof=this.rules.getNumber("ROF"),this.sabotageCursor=this.rules.getBool("SabotageCursor"),this.spawner=this.rules.getBool("Spawner");var e=this.rules.getNumber("Speed");this.iniSpeed=e,this.speed=ObjectRules.iniSpeedToLeptonsPerTick(e,100),this.suicide=this.rules.getBool("Suicide"),this.useSparkParticles=this.rules.getBool("UseSparkParticles"),this.warhead=this.rules.getString("Warhead")}}class AudioVisualRules{readIni(e){this.ini=e,this.ambientChangeRate=e.getNumber("AmbientChangeRate"),this.ambientChangeStep=e.getNumber("AmbientChangeStep"),this.behind=e.getString("Behind"),this.bridgeExplosions=e.getArray("BridgeExplosions"),this.chronoBeamColor=e.getNumberArray("ChronoBeamColor"),this.chronoBlast=e.getString("ChronoBlast"),this.chronoBlastDest=e.getString("ChronoBlastDest"),this.chronoPlacement=e.getString("ChronoPlacement"),this.chronoSparkle1=e.getString("ChronoSparkle1"),this.conditionRed=e.getNumber("ConditionRed"),this.conditionYellow=e.getNumber("ConditionYellow"),this.creditTicks=e.getArray("CreditTicks"),this.extraAircraftLight=e.getNumber("ExtraAircraftLight"),this.extraInfantryLight=e.getNumber("ExtraInfantryLight"),this.extraUnitLight=e.getNumber("ExtraUnitLight");let t=e.getString("DamageFireTypes");t=t||"FIRE01,FIRE02,FIRE03",this.fireNames=t.split(/\.|,/).filter(e=>""!==e),this.flyerHelper=e.getString("FlyerHelper"),this.gravity=e.getNumber("Gravity"),this.idleActionFrequency=60*e.getNumber("IdleActionFrequency"),this.impactLandSound=e.getString("ImpactLandSound")||void 0,this.impactWaterSound=e.getString("ImpactWaterSound")||void 0,this.infantryExplode=e.getString("InfantryExplode"),this.flamingInfantry=e.getString("FlamingInfantry"),this.infantryHeadPop=e.getString("InfantryHeadPop"),this.infantryNuked=e.getString("InfantryNuked"),this.ironCurtainInvokeAnim=e.getString("IronCurtainInvokeAnim"),this.messageDuration=e.getNumber("MessageDuration",10),this.metallicDebris=e.getArray("MetallicDebris"),this.nukeTakeOff=e.getString("NukeTakeOff"),this.deadBodies=e.getArray("DeadBodies"),this.wake=e.getString("Wake"),this.parachute=e.getString("Parachute"),this.moveFlash=e.getString("MoveFlash"),this.warpOut=e.getString("WarpOut"),this.warpAway=e.getString("WarpAway"),this.weaponNullifyAnim=e.getString("WeaponNullifyAnim"),this.weatherConClouds=e.getArray("WeatherConClouds"),this.weatherConBoltExplosion=e.getString("WeatherConBoltExplosion"),this.weatherConBolts=e.getArray("WeatherConBolts")}}!function(e){e[e.GenericCombat=0]="GenericCombat",e[e.GenericNonCombat=1]="GenericNonCombat",e[e.DropZone=2]="DropZone",e[e.BaseUnderAttack=3]="BaseUnderAttack",e[e.HarvesterUnderAttack=4]="HarvesterUnderAttack",e[e.EnemyObjectSensed=5]="EnemyObjectSensed"}(RadarEventType=RadarEventType||{});class RadarRules{readIni(e){return this.eventSuppressionDistances=e.getNumberArray("RadarEventSuppressionDistances"),this.eventVisibilityDurations=e.getNumberArray("RadarEventVisibilityDurations"),this.eventDurations=e.getNumberArray("RadarEventDurations"),this.flashFrameTime=e.getNumber("FlashFrameTime"),this.combatFlashTime=e.getNumber("RadarCombatFlashTime"),this.eventMinRadius=e.getNumber("RadarEventMinRadius"),this.eventSpeed=e.getNumber("RadarEventSpeed"),this.eventRotationSpeed=e.getNumber("RadarEventRotationSpeed"),this.eventColorSpeed=e.getNumber("RadarEventColorSpeed"),this}getEventSuppresionDistance(e){if(e>this.eventSuppressionDistances.length-1)throw new RangeError("No event suppression distance is defined for type "+RadarEventType[e]);return this.eventSuppressionDistances[e]}getEventVisibilityDuration(e){if(e>this.eventVisibilityDurations.length-1)throw new RangeError("No event visibility duration is defined for type "+RadarEventType[e]);return this.eventVisibilityDurations[e]}getEventDuration(e){if(e>this.eventDurations.length-1)throw new RangeError("No event duration is defined for type "+RadarEventType[e]);return this.eventDurations[e]}}class RepairRules{readIni(e){return this.reloadRate=e.getNumber("ReloadRate"),this.repairPercent=e.getNumber("RepairPercent"),this.repairRate=e.getNumber("RepairRate"),this.repairStep=e.getNumber("RepairStep"),this.uRepairRate=e.getNumber("URepairRate"),this.iRepairRate=e.getNumber("IRepairRate"),this.iRepairStep=e.getNumber("IRepairStep"),this}}class VeteranRules{readIni(e){return this.veteranRatio=e.getNumber("VeteranRatio",3),this.veteranCombat=e.getNumber("VeteranCombat",1),this.veteranSpeed=e.getNumber("VeteranSpeed",1),this.veteranSight=Math.max(1,e.getNumber("VeteranSight",1)),this.veteranArmor=e.getNumber("VeteranArmor",1),this.veteranROF=e.getNumber("VeteranROF",1),this.veteranCap=e.getNumber("VeteranCap",2),this.initialVeteran=e.getBool("InitialVeteran"),this}}class CrewRules{readIni(e){return this.alliedCrew=e.getString("AlliedCrew"),this.alliedSurvivorDivisor=e.getNumber("AlliedSurvivorDivisor"),this.crewEscape=e.getNumber("CrewEscape"),this.sovietCrew=e.getString("SovietCrew"),this.sovietSurvivorDivisor=e.getNumber("SovietSurvivorDivisor"),this.survivorRate=e.getNumber("SurvivorRate"),this.thirdCrew=e.getString("ThirdCrew"),this.thirdSurvivorDivisor=e.getNumber("ThirdSurvivorDivisor"),this}}class PrismRules{readIni(e){return this.type=e.getString("PrismType"),this.supportHeight=e.getNumber("PrismSupportHeight"),this.supportMax=e.getNumber("PrismSupportMax"),this.supportModifier=e.getNumber("PrismSupportModifier",1),this}}class ThreatRules{readIni(e){return this.myEffectivenessCoefficientDefault=e.getNumber("MyEffectivenessCoefficientDefault"),this.targetEffectivenessCoefficientDefault=e.getNumber("TargetEffectivenessCoefficientDefault"),this.targetSpecialThreatCoefficientDefault=e.getNumber("TargetSpecialThreatCoefficientDefault"),this.targetStrengthCoefficientDefault=e.getNumber("TargetStrengthCoefficientDefault"),this.targetDistanceCoefficientDefault=e.getNumber("TargetDistanceCoefficientDefault"),this}}class ParadropRules{readIni(e){if(this.allyParaDrop=this.readParadropSquad(e.getArray("AllyParaDropInf"),e.getNumberArray("AllyParaDropNum"),"Ally"),this.amerParaDrop=this.readParadropSquad(e.getArray("AmerParaDropInf"),e.getNumberArray("AmerParaDropNum"),"Amer"),this.sovParaDrop=this.readParadropSquad(e.getArray("SovParaDropInf"),e.getNumberArray("SovParaDropNum"),"Sov"),this.yuriParaDrop=this.readParadropSquad(e.getArray("YuriParaDropInf"),e.getNumberArray("YuriParaDropNum"),"Yuri"),this.paradropPlane=e.getString("ParadropPlane"),!this.paradropPlane)throw new Error("Missing rules [General]->ParadropPlane");return this.paradropRadius=e.getNumber("ParadropRadius"),this}readParadropSquad(t,i,e){if(t.length!==i.length)throw new RangeError(`${e}ParaDropInf/Num size mismatch (${t.length}, ${i.length})`);let r=[];for(let e=0;e<t.length;++e)0<i[e]&&r.push({inf:t[e],num:i[e]});return r}getParadropSquads(e){switch(e){case SideType.GDI:return this.allyParaDrop;case SideType.Nod:return this.sovParaDrop;case SideType.ThirdSide:return this.yuriParaDrop;default:throw new Error(`Unhandled side type "${e}"`)}}}class LightningStormRules{readIni(e){return this.deferment=e.getNumber("LightningDeferment"),this.damage=e.getNumber("LightningDamage"),this.duration=e.getNumber("LightningStormDuration"),this.warhead=e.getString("LightningWarhead"),this.hitDelay=e.getNumber("LightningHitDelay"),this.scatterDelay=e.getNumber("LightningScatterDelay"),this.cellSpread=e.getNumber("LightningCellSpread"),this.separation=e.getNumber("LightningSeparation"),this}}class MissileRules{}class V3RocketRules extends MissileRules{readIni(e){return this.pauseFrames=e.getNumber("V3RocketPauseFrames"),this.tiltFrames=e.getNumber("V3RocketTiltFrames"),this.pitchInitial=e.getNumber("V3RocketPitchInitial"),this.pitchFinal=e.getNumber("V3RocketPitchFinal"),this.turnRate=e.getNumber("V3RocketTurnRate"),this.acceleration=e.getNumber("V3RocketAcceleration"),this.altitude=e.getNumber("V3RocketAltitude"),this.damage=e.getNumber("V3RocketDamage"),this.eliteDamage=e.getNumber("V3RocketEliteDamage"),this.bodyLength=e.getNumber("V3RocketBodyLength"),this.lazyCurve=e.getBool("V3RocketLazyCurve"),this.type=e.getString("V3RocketType"),this}}class DMislRules extends MissileRules{readIni(e){return this.pauseFrames=e.getNumber("DMislPauseFrames"),this.tiltFrames=e.getNumber("DMislTiltFrames"),this.pitchInitial=e.getNumber("DMislPitchInitial"),this.pitchFinal=e.getNumber("DMislPitchFinal"),this.turnRate=e.getNumber("DMislTurnRate"),this.acceleration=e.getNumber("DMislAcceleration"),this.altitude=e.getNumber("DMislAltitude"),this.damage=e.getNumber("DMislDamage"),this.eliteDamage=e.getNumber("DMislEliteDamage"),this.bodyLength=e.getNumber("DMislBodyLength"),this.lazyCurve=e.getBool("DMislLazyCurve"),this.type=e.getString("DMislType"),this}}class HoverRules{readIni(e){return this.height=e.getNumber("HoverHeight"),this.dampen=e.getNumber("HoverDampen"),this.bob=e.getNumber("HoverBob"),this.boost=e.getNumber("HoverBoost"),this.acceleration=e.getNumber("HoverAcceleration"),this.brake=e.getNumber("HoverBrake"),this}}!function(e){e[e.Power=0]="Power",e[e.Factory=1]="Factory",e[e.Barracks=2]="Barracks",e[e.Radar=3]="Radar",e[e.Tech=4]="Tech",e[e.Proc=5]="Proc"}(PrereqCategory=PrereqCategory||{});const prereqCategIniKeys=(new Map).set(PrereqCategory.Power,"PrerequisitePower").set(PrereqCategory.Factory,"PrerequisiteFactory").set(PrereqCategory.Barracks,"PrerequisiteBarracks").set(PrereqCategory.Radar,"PrerequisiteRadar").set(PrereqCategory.Tech,"PrerequisiteTech").set(PrereqCategory.Proc,"PrerequisiteProc");class GeneralRules{constructor(){this.prereqCategories=new Map}readIni(e){this.aircraftFogReveal=e.getNumber("AircraftFogReveal"),this.alliedDisguise=e.getString("AlliedDisguise"),this.baseUnit=e.getArray("BaseUnit"),this.bridgeVoxelMax=e.getNumber("BridgeVoxelMax"),this.buildSpeed=e.getFixed("BuildSpeed"),this.buildupTime=e.getNumber("BuildupTime"),this.chronoDelay=e.getNumber("ChronoDelay"),this.chronoDistanceFactor=e.getNumber("ChronoDistanceFactor",32),this.chronoHarvTooFarDistance=e.getNumber("ChronoHarvTooFarDistance"),this.chronoMinimumDelay=e.getNumber("ChronoMinimumDelay"),this.chronoRangeMinimum=e.getNumber("ChronoRangeMinimum"),this.chronoTrigger=e.getBool("ChronoTrigger",!0),this.cliffBackImpassability=e.getNumber("CliffBackImpassability",2),this.cloakDelay=e.getNumber("CloakDelay"),this.closeEnough=e.getNumber("CloseEnough"),this.crew=(new CrewRules).readIni(e),this.defaultMirageDisguises=e.getArray("DefaultMirageDisguises"),this.dMisl=(new DMislRules).readIni(e),this.dropPodWeapon=e.getString("DropPodWeapon"),this.engineer=e.getString("Engineer"),this.engineerCaptureLevel=e.getFixed("EngineerCaptureLevel",.25),this.engineerDamage=e.getFixed("EngineerDamage",.437),this.engineerAlwaysCaptureTech=e.getBool("EngineerAlwaysCaptureTech",!0),this.flightLevel=e.getNumber("FlightLevel"),this.guardAreaTargetingDelay=e.getNumber("GuardAreaTargetingDelay"),this.harvesterTooFarDistance=e.getNumber("HarvesterTooFarDistance"),this.harvesterUnit=e.getArray("HarvesterUnit"),this.hover=(new HoverRules).readIni(e),this.infantryBlinkDisguiseTime=e.getNumber("InfantryBlinkDisguiseTime"),this.lightningStorm=(new LightningStormRules).readIni(e),this.lowPowerPenaltyModifier=e.getNumber("LowPowerPenaltyModifier",1),this.minLowPowerProductionSpeed=e.getFixed("MinLowPowerProductionSpeed",.5),this.maxLowPowerProductionSpeed=e.getFixed("MaxLowPowerProductionSpeed",1),this.maximumCheerRate=e.getNumber("MaximumCheerRate"),this.maximumQueuedObjects=e.getNumber("MaximumQueuedObjects"),this.maxWaypointPathLength=e.getNumber("MaxWaypointPathLength"),this.multipleFactory=e.getFixed("MultipleFactory",1),this.normalTargetingDelay=e.getNumber("NormalTargetingDelay"),this.padAircraft=e.getArray("PadAircraft"),this.parachuteMaxFallRate=e.getNumber("ParachuteMaxFallRate"),this.paradrop=(new ParadropRules).readIni(e),this.prism=(new PrismRules).readIni(e),this.purifierBonus=e.getNumber("PurifierBonus"),this.radar=(new RadarRules).readIni(e),this.refundPercent=clamp(e.getNumber("RefundPercent"),0,1),this.repair=(new RepairRules).readIni(e),this.returnStructures=e.getBool("ReturnStructures"),this.revealTriggerRadius=Math.min(10,e.getNumber("RevealTriggerRadius")),this.shipSinkingWeight=e.getNumber("ShipSinkingWeight"),this.sovietDisguise=e.getString("SovietDisguise"),this.spyMoneyStealPercent=e.getNumber("SpyMoneyStealPercent"),this.spyPowerBlackout=e.getNumber("SpyPowerBlackout"),this.technician=e.getString("Technician"),this.thirdDisguise=e.getString("ThirdDisguise"),this.threat=(new ThreatRules).readIni(e),this.treeStrength=e.getNumber("TreeStrength"),this.unitsUnsellable=e.getBool("UnitsUnsellable"),this.v3Rocket=(new V3RocketRules).readIni(e),this.veteran=(new VeteranRules).readIni(e),this.wallBuildSpeedCoefficient=e.getFixed("WallBuildSpeedCoefficient"),this.readPrereqCategories(e)}readPrereqCategories(e){for(var[t,i]of prereqCategIniKeys){if(!e.has(i))throw new Error(`Missing prerequisite category ${i} in [General] section`);this.prereqCategories.set(t,e.getArray(i))}}getMissileRules(e){switch(e){case this.v3Rocket.type:return this.v3Rocket;case this.dMisl.type:return this.dMisl;default:throw new Error(`Unsupported missile type "${e}"`)}}}!function(e){e[e.Default=0]="Default",e[e.Tunnel=5]="Tunnel",e[e.Railroad=6]="Railroad",e[e.Rock1=7]="Rock1",e[e.Rock2=8]="Rock2",e[e.Water=9]="Water",e[e.Shore=10]="Shore",e[e.Pavement=11]="Pavement",e[e.Dirt=12]="Dirt",e[e.Clear=13]="Clear",e[e.Rough=14]="Rough",e[e.Cliff=15]="Cliff"}(TerrainType=TerrainType||{}),function(e){e[e.Clear=0]="Clear",e[e.Road=1]="Road",e[e.Rock=2]="Rock",e[e.Beach=3]="Beach",e[e.Rough=4]="Rough",e[e.Railroad=5]="Railroad",e[e.Weeds=6]="Weeds",e[e.Water=7]="Water",e[e.Wall=8]="Wall",e[e.Tiberium=9]="Tiberium",e[e.Cliff=10]="Cliff"}(LandType=LandType||{});const terrainToLandType=new Map([[TerrainType.Default,LandType.Clear],[TerrainType.Clear,LandType.Clear],[TerrainType.Tunnel,LandType.Cliff],[TerrainType.Railroad,LandType.Railroad],[TerrainType.Rock1,LandType.Rock],[TerrainType.Rock2,LandType.Rock],[TerrainType.Water,LandType.Water],[TerrainType.Shore,LandType.Beach],[TerrainType.Pavement,LandType.Road],[TerrainType.Dirt,LandType.Road],[TerrainType.Rough,LandType.Rough],[TerrainType.Cliff,LandType.Cliff]]);function getLandType(e){if(!terrainToLandType.has(e))throw new Error("Unknown terrain type "+e);return terrainToLandType.get(e)}!function(e){e[e.Foot=0]="Foot",e[e.Track=1]="Track",e[e.Wheel=2]="Wheel",e[e.Hover=3]="Hover",e[e.Float=4]="Float",e[e.FloatBeach=5]="FloatBeach",e[e.Amphibious=6]="Amphibious",e[e.Winged=7]="Winged"}(SpeedType=SpeedType||{});class LandRules{constructor(){this.speedModifiers=new Map}readIni(t){return this.buildable=t.getBool("Buildable",!1),[...t.entries.keys()].forEach(e=>{void 0!==SpeedType[e]&&this.speedModifiers.set(SpeedType[e],t.getNumber(e))}),this}getSpeedModifier(e){if(e===SpeedType.Foot&&0===this.speedModifiers.get(SpeedType.Track))return 0;let t=this.speedModifiers.get(e);return void 0===t&&(t=1),e!==SpeedType.Track&&e!==SpeedType.Wheel&&0<t&&(t=1),t}}!function(e){e[e.None=0]="None",e[e.Gunfire=1]="Gunfire",e[e.Explode=2]="Explode",e[e.ExplodeAlt=3]="ExplodeAlt",e[e.Fire=4]="Fire",e[e.Electro=5]="Electro",e[e.HeadExplode=6]="HeadExplode",e[e.Nuke=7]="Nuke"}(InfDeathType=InfDeathType||{});class WarheadRules{constructor(e){this.rules=e,this.verses=new Map,this.parse()}get name(){return this.rules.name}parse(){this.affectsAllies=this.rules.getBool("AffectsAllies",!0),this.animList=this.rules.getArray("AnimList"),this.bombDisarm=this.rules.getBool("BombDisarm"),this.bullets=this.rules.getBool("Bullets"),this.causesDelayKill=this.rules.getBool("CausesDelayKill"),this.cellSpread=this.rules.getNumber("CellSpread"),this.conventional=this.rules.getBool("Conventional"),this.culling=this.rules.getBool("Culling"),this.delayKillAtMax=this.rules.getNumber("DelayKillAtMax"),this.delayKillFrames=this.rules.getNumber("DelayKillFrames"),this.electricAssault=this.rules.getBool("ElectricAssault"),this.emEffect=this.rules.getBool("EMEffect"),this.infDeath=this.rules.getEnumNumeric("InfDeath",InfDeathType,InfDeathType.None),this.ivanBomb=this.rules.getBool("IvanBomb"),this.makesDisguise=this.rules.getBool("MakesDisguise"),this.mindControl=this.rules.getBool("MindControl"),this.nukeMaker=this.rules.getBool("NukeMaker"),this.paralyzes=this.rules.getNumber("Paralyzes"),this.parasite=this.rules.getBool("Parasite"),this.percentAtMax=this.rules.getNumber("PercentAtMax",1),this.proneDamage=this.rules.getFixed("ProneDamage",1),this.psychicDamage=this.rules.getBool("PsychicDamage"),this.radiation=this.rules.getBool("Radiation"),this.rocker=this.rules.getBool("Rocker"),this.sonic=this.rules.getBool("Sonic"),this.temporal=this.rules.getBool("Temporal");let e=this.rules.getFixedArray("Verses");e.forEach((e,t)=>this.verses.set(t,e)),this.wallAbsoluteDestroyer=this.rules.getBool("WallAbsoluteDestroyer"),this.wall=this.rules.getBool("Wall"),this.wood=this.rules.getBool("Wood")}}class ProjectileRules extends ObjectRules{parse(){super.parse();var e=this.ini.getNumber("ROT",0);let t=this.ini.getNumber("Acceleration");1!==e||t||(t=Number.POSITIVE_INFINITY),t=t||3,this.acceleration=t,this.arcing=this.ini.getBool("Arcing"),this.courseLockDuration=this.ini.getNumber("CourseLockDuration"),this.detonationAltitude=this.ini.getNumber("DetonationAltitude"),this.firersPalette=this.ini.getBool("FirersPalette"),this.flakScatter=this.ini.getBool("FlakScatter"),this.inaccurate=this.ini.getBool("Inaccurate"),this.inviso=this.ini.getBool("Inviso"),this.isAntiAir=this.ini.getBool("AA"),this.isAntiGround=this.ini.getBool("AG",!0),this.level=this.ini.getBool("Level"),this.rot=ObjectRules.iniRotToDegsPerTick(e),this.iniRot=e,this.shadow=this.ini.getBool("Shadow",!0),this.shrapnelWeapon=this.ini.getString("ShrapnelWeapon")||void 0,this.shrapnelCount=this.ini.getNumber("ShrapnelCount"),this.subjectToCliffs=this.ini.getBool("SubjectToCliffs"),this.subjectToElevation=this.ini.getBool("SubjectToElevation"),this.subjectToWalls=this.ini.getBool("SubjectToWalls"),this.vertical=this.ini.getBool("Vertical")}}!function(e){e[e.Green=0]="Green",e[e.Yellow=1]="Yellow",e[e.White=2]="White",e[e.Red=3]="Red",e[e.Blue=4]="Blue"}(PipColor=PipColor||{}),function(e){e[e.Statue=0]="Statue",e[e.Aircraft=1]="Aircraft",e[e.Chrono=2]="Chrono",e[e.Hover=3]="Hover",e[e.Infantry=4]="Infantry",e[e.Jumpjet=5]="Jumpjet",e[e.Missile=6]="Missile",e[e.Ship=7]="Ship",e[e.Vehicle=8]="Vehicle"}(LocomotorType=LocomotorType||{});const locomotorTypesByClsId=new Map([["{4A582746-9839-11d1-B709-00A024DDAFD1}",LocomotorType.Aircraft],["{4A582747-9839-11d1-B709-00A024DDAFD1}",LocomotorType.Chrono],["{4A582742-9839-11d1-B709-00A024DDAFD1}",LocomotorType.Hover],["{4A582744-9839-11d1-B709-00A024DDAFD1}",LocomotorType.Infantry],["{92612C46-F71F-11d1-AC9F-006008055BB5}",LocomotorType.Jumpjet],["{B7B49766-E576-11d3-9BD9-00104B972FE8}",LocomotorType.Missile],["{2BEA74E1-7CCA-11d3-BE14-00104B62A16C}",LocomotorType.Ship],["{4A582741-9839-11d1-B709-00A024DDAFD1}",LocomotorType.Vehicle]]),defaultSpeedsByLocomotor=new Map([[LocomotorType.Infantry,SpeedType.Foot],[LocomotorType.Ship,SpeedType.Float],[LocomotorType.Hover,SpeedType.Hover],[LocomotorType.Jumpjet,SpeedType.Winged],[LocomotorType.Aircraft,SpeedType.Winged],[LocomotorType.Missile,SpeedType.Winged]]);!function(e){e[e.Amphibious=0]="Amphibious",e[e.AmphibiousCrusher=1]="AmphibiousCrusher",e[e.AmphibiousDestroyer=2]="AmphibiousDestroyer",e[e.Crusher=3]="Crusher",e[e.CrusherAll=4]="CrusherAll",e[e.Destroyer=5]="Destroyer",e[e.Fly=6]="Fly",e[e.Infantry=7]="Infantry",e[e.InfantryDestroyer=8]="InfantryDestroyer",e[e.Normal=9]="Normal",e[e.Subterranean=10]="Subterranean",e[e.Water=11]="Water"}(MovementZone=MovementZone||{}),function(e){e[e.None=0]="None",e[e.Flak=1]="Flak",e[e.Plate=2]="Plate",e[e.Light=3]="Light",e[e.Medium=4]="Medium",e[e.Heavy=5]="Heavy",e[e.Wood=6]="Wood",e[e.Steel=7]="Steel",e[e.Concrete=8]="Concrete",e[e.Special_1=9]="Special_1",e[e.Special_2=10]="Special_2"}(ArmorType=ArmorType||{}),function(e){e[e.LandOk=0]="LandOk",e[e.LandNotOk=1]="LandNotOk",e[e.LandSecondary=2]="LandSecondary"}(LandTargeting=LandTargeting||{}),function(e){e[e.UnderwaterNever=0]="UnderwaterNever",e[e.UnderwaterSecondary=1]="UnderwaterSecondary",e[e.UnderwaterOnly=2]="UnderwaterOnly",e[e.OrganicSecondary=3]="OrganicSecondary",e[e.SealSpecial=4]="SealSpecial",e[e.NavalAll=5]="NavalAll",e[e.NavalNone=6]="NavalNone"}(NavalTargeting=NavalTargeting||{}),function(e){e[e.Primary=0]="Primary",e[e.Secondary=1]="Secondary",e[e.DeathWeapon=2]="DeathWeapon"}(WeaponType=WeaponType||{}),function(e){e[e.FASTER=0]="FASTER",e[e.STRONGER=1]="STRONGER",e[e.FIREPOWER=2]="FIREPOWER",e[e.SCATTER=3]="SCATTER",e[e.ROF=4]="ROF",e[e.SIGHT=5]="SIGHT",e[e.SELF_HEAL=6]="SELF_HEAL",e[e.CLOAK=7]="CLOAK",e[e.EXPLODES=8]="EXPLODES",e[e.RADAR_INVISIBLE=9]="RADAR_INVISIBLE",e[e.SENSORS=10]="SENSORS",e[e.FEARLESS=11]="FEARLESS",e[e.C4=12]="C4",e[e.GUARD_AREA=13]="GUARD_AREA",e[e.CRUSHER=14]="CRUSHER"}(VeteranAbility=VeteranAbility||{}),function(e){e[e.None=0]="None",e[e.Normal=1]="Normal",e[e.Strong=2]="Strong"}(VhpScan=VhpScan||{}),function(e){e[e.Combat=0]="Combat",e[e.Tech=1]="Tech",e[e.Resource=2]="Resource",e[e.Power=3]="Power"}(BuildCat=BuildCat||{}),function(e){e[e.None=0]="None",e[e.BuildingType=1]="BuildingType",e[e.InfantryType=2]="InfantryType",e[e.UnitType=3]="UnitType",e[e.NavalUnitType=4]="NavalUnitType",e[e.AircraftType=5]="AircraftType"}(FactoryType=FactoryType||{});class TechnoRules extends ObjectRules{constructor(e,t,i,r){super(e,t,i,r)}parse(){super.parse(),this.owner=this.ini.getArray("Owner");var e=this.ini.getNumber("AIBasePlanningSide");this.aiBasePlanningSide=-1!==e&&void 0!==SideType[e]?e:void 0,this.requiredHouses=this.ini.getArray("RequiredHouses"),this.forbiddenHouses=this.ini.getArray("ForbiddenHouses"),this.requiresStolenAlliedTech=this.ini.getBool("RequiresStolenAlliedTech"),this.requiresStolenSovietTech=this.ini.getBool("RequiresStolenSovietTech"),this.requiresStolenThirdTech=this.ini.getBool("RequiresStolenThirdTech"),this.techLevel=this.ini.getNumber("TechLevel",-1),this.cost=this.ini.getNumber("Cost"),this.points=this.ini.getNumber("Points"),this.power=this.ini.getNumber("Power"),this.powered=this.ini.getBool("Powered"),this.prerequisite=this.ini.getArray("Prerequisite"),this.prerequisiteOverride=this.ini.getArray("PrerequisiteOverride"),this.soylent=this.ini.getNumber("Soylent"),this.crateGoodie=this.ini.getBool("CrateGoodie"),this.buildCat=this.ini.getEnum("BuildCat",BuildCat,BuildCat.Combat),this.adjacent=this.ini.getNumber("Adjacent",1),this.baseNormal=this.ini.getBool("BaseNormal",!0),this.buildLimit=this.ini.getNumber("BuildLimit",Number.POSITIVE_INFINITY),this.airRangeBonus=this.ini.getNumber("AirRangeBonus"),this.guardRange=this.ini.getNumber("GuardRange"),this.defaultToGuardArea=this.ini.getBool("DefaultToGuardArea"),this.eligibileForAllyBuilding=this.ini.getBool("EligibileForAllyBuilding"),this.numberImpassableRows=this.ini.getNumber("NumberImpassableRows"),this.bridgeRepairHut=this.ini.getBool("BridgeRepairHut"),this.constructionYard=this.ini.getBool("ConstructionYard"),this.refinery=this.ini.getBool("Refinery"),this.unitRepair=this.ini.getBool("UnitRepair"),this.unitReload=this.ini.getBool("UnitReload"),this.unitSell=this.ini.getBool("UnitSell"),this.isBaseDefense=this.ini.getBool("IsBaseDefense"),this.superWeapon=this.parseWeaponName(this.ini.getString("SuperWeapon")),this.chargedAnimTime=this.ini.getNumber("ChargedAnimTime");var t=this.ini.getBool("Naval");this.naval=t,this.underwater=this.ini.getBool("Underwater"),this.waterBound=this.ini.getBool("WaterBound"),this.orePurifier=this.ini.getBool("OrePurifier"),this.cloning=this.ini.getBool("Cloning"),this.grinding=this.ini.getBool("Grinding"),this.nukeSilo=this.ini.getBool("NukeSilo"),this.repairable=this.ini.getBool("Repairable",this.type===ObjectType.Building),this.clickRepairable=this.ini.getBool("ClickRepairable",this.type===ObjectType.Building),this.unsellable=this.ini.getBool("Unsellable",this.type!==ObjectType.Building&&this.generalRules.unitsUnsellable),this.returnable=this.ini.getBool("Returnable",this.generalRules.returnStructures),this.gdiBarracks=this.ini.getBool("GDIBarracks"),this.nodBarracks=this.ini.getBool("NODBarracks"),this.numberOfDocks=this.ini.getNumber("NumberOfDocks"),this.unitRepair&&!this.numberOfDocks&&(this.numberOfDocks=1),this.factory=this.ini.getEnum("Factory",FactoryType,FactoryType.None),this.factory===FactoryType.UnitType&&t&&(this.factory=FactoryType.NavalUnitType),this.weaponsFactory=this.ini.getBool("WeaponsFactory"),this.helipad=this.ini.getBool("Helipad"),this.hospital=this.ini.getBool("Hospital"),this.landTargeting=this.ini.getEnumNumeric("LandTargeting",LandTargeting,LandTargeting.LandOk),this.navalTargeting=this.ini.getEnumNumeric("NavalTargeting",NavalTargeting,NavalTargeting.UnderwaterNever),this.tooBigToFitUnderBridge=this.ini.getBool("TooBigToFitUnderBridge",this.type===ObjectType.Building),this.canBeOccupied=this.ini.getBool("CanBeOccupied"),this.maxNumberOccupants=this.ini.getNumber("MaxNumberOccupants"),this.leaveRubble=this.ini.getBool("LeaveRubble"),this.undeploysInto=this.ini.getString("UndeploysInto"),this.deploysInto=this.ini.getString("DeploysInto"),this.deployTime=this.ini.getNumber("DeployTime"),this.capturable=this.ini.getBool("Capturable"),this.spyable=this.ini.getBool("Spyable"),this.needsEngineer=this.ini.getBool("NeedsEngineer"),this.c4=this.ini.getBool("C4"),this.canC4=this.ini.getBool("CanC4",!0),this.eligibleForDelayKill=this.ini.getBool("EligibleForDelayKill"),this.produceCashStartup=this.ini.getNumber("ProduceCashStartup"),this.produceCashAmount=this.ini.getNumber("ProduceCashAmount"),this.produceCashDelay=this.ini.getNumber("ProduceCashDelay"),this.explosion=this.ini.getArray("Explosion"),this.explodes=this.ini.getBool("Explodes"),this.ifvMode=this.ini.getNumber("IFVMode"),this.turretIndexesByIfvMode=this.parseTurretIndexes(),this.turret=this.ini.getBool("Turret"),this.turretCount=this.ini.getNumber("TurretCount",this.turret?1:0),this.turretAnim=this.ini.getString("TurretAnim"),this.turretAnimIsVoxel=this.ini.getBool("TurretAnimIsVoxel"),this.turretAnimX=this.ini.getNumber("TurretAnimX"),this.turretAnimY=this.ini.getNumber("TurretAnimY"),this.turretAnimZAdjust=this.ini.getNumber("TurretAnimZAdjust"),this.isChargeTurret=this.ini.getBool("IsChargeTurret"),this.overpowerable=this.ini.getBool("Overpowerable"),this.freeUnit=this.ini.getString("FreeUnit"),this.primary=this.parseWeaponName(this.ini.getString("Primary")),this.secondary=this.parseWeaponName(this.ini.getString("Secondary")),this.elitePrimary=this.parseWeaponName(this.ini.getString("ElitePrimary")),this.eliteSecondary=this.parseWeaponName(this.ini.getString("EliteSecondary")),this.weaponCount=this.ini.getNumber("WeaponCount"),this.deathWeapon=this.parseWeaponName(this.ini.getString("DeathWeapon")),this.deathWeaponDamageModifier=this.ini.getNumber("DeathWeaponDamageModifier",1),this.occupyWeapon=this.parseWeaponName(this.ini.getString("OccupyWeapon")),this.eliteOccupyWeapon=this.parseWeaponName(this.ini.getString("EliteOccupyWeapon")),this.veteranAbilities=new Set(this.ini.getEnumArray("VeteranAbilities",VeteranAbility)),this.eliteAbilities=new Set([...this.veteranAbilities,...this.ini.getEnumArray("EliteAbilities",VeteranAbility)]),this.selfHealing=this.ini.getBool("SelfHealing"),this.wall=this.ini.getBool("Wall"),this.gate=this.ini.getBool("Gate"),this.armor=this.ini.getEnum("Armor",ArmorType,ArmorType.None,!0),this.strength=Math.floor(this.ini.getNumber("Strength")),this.immune=this.ini.getBool("Immune"),this.immuneToRadiation=this.ini.getBool("ImmuneToRadiation"),this.immuneToPsionics=this.ini.getBool("ImmuneToPsionics"),this.typeImmune=this.ini.getBool("TypeImmune"),this.damageSelf=this.ini.getBool("DamageSelf"),this.warpable=this.ini.getBool("Warpable",!0),this.isTilter=this.ini.getBool("IsTilter",!0),this.walkRate=this.ini.getNumber("WalkRate",1),this.idleRate=this.ini.getNumber("IdleRate",0),this.noSpawnAlt=this.ini.getBool("NoSpawnAlt"),this.crusher=this.ini.getBool("Crusher"),this.consideredAircraft=this.ini.getBool("ConsideredAircraft"),this.crashable=this.ini.getBool("Crashable");var i=this.ini.getBool("Landable");this.landable=i,this.airportBound=this.ini.getBool("AirportBound"),this.balloonHover=this.ini.getBool("BalloonHover"),this.hoverAttack=this.ini.getBool("HoverAttack"),this.omniFire=this.ini.getBool("OmniFire"),this.fighter=this.ini.getBool("Fighter"),this.flightLevel=this.ini.getNumber("FlightLevel")||void 0;var r=this.ini.getString("Locomotor"),e=this.type===ObjectType.Building?LocomotorType.Statue:LocomotorType.Chrono;if(r?(t=locomotorTypesByClsId.get(r))?this.locomotor=t:(console.warn(`Object rules "${this.name}" has invalid Locomotor "${r}"`),this.locomotor=e):this.locomotor=e,this.locomotor!==LocomotorType.Statue){let e=defaultSpeedsByLocomotor.get(this.locomotor);void 0===e&&(this.type===ObjectType.Aircraft||this.consideredAircraft?e=SpeedType.Winged:this.type===ObjectType.Vehicle?e=this.crusher?SpeedType.Track:SpeedType.Wheel:this.type===ObjectType.Infantry&&(e=SpeedType.Foot)),this.speedType=this.ini.getEnum("SpeedType",SpeedType,e,!0)}e=[LocomotorType.Ship,LocomotorType.Vehicle,LocomotorType.Chrono].includes(this.locomotor)?65:100;this.speed=ObjectRules.iniSpeedToLeptonsPerTick(this.ini.getNumber("Speed"),e),this.movementZone=this.ini.getEnum("MovementZone",MovementZone,MovementZone.Normal),this.fearless=this.ini.getBool("Fearless"),this.deployer=this.ini.getBool("Deployer"),this.deployFire=this.ini.getBool("DeployFire"),this.deployFireWeapon=this.ini.getNumber("DeployFireWeapon",WeaponType.Secondary),this.undeployDelay=this.ini.getNumber("UndeployDelay"),this.fraidycat=this.ini.getBool("Fraidycat",!1),this.isHuman=!this.ini.getBool("NotHuman"),this.organic=this.type===ObjectType.Infantry||this.ini.getBool("Organic"),this.occupier=this.ini.getBool("Occupier"),this.engineer=this.ini.getBool("Engineer"),this.ivan=this.ini.getBool("Ivan"),this.civilian=this.ini.getBool("Civilian"),this.agent=this.ini.getBool("Agent"),this.infiltrate=this.ini.getBool("Infiltrate"),this.threatPosed=this.ini.getNumber("ThreatPosed"),this.specialThreatValue=this.ini.getNumber("SpecialThreatValue"),this.canPassiveAquire=this.ini.getBool("CanPassiveAquire",!0),this.canRetaliate=this.ini.getBool("CanRetaliate",!0),this.preventAttackMove=this.ini.getBool("PreventAttackMove"),this.opportunityFire=this.ini.getBool("OpportunityFire"),this.distributedFire=this.ini.getBool("DistributedFire"),this.radialFireSegments=this.ini.getNumber("RadialFireSegments"),this.attackCursorOnFriendlies=this.ini.getBool("AttackCursorOnFriendlies"),this.bombable=this.ini.getBool("Bombable",!0),this.trainable=this.ini.getBool("Trainable",this.type!==ObjectType.Building),this.crewed=this.ini.getBool("Crewed"),this.parasiteable=this.ini.getBool("Parasiteable",this.type!==ObjectType.Building),this.suppressionThreshold=this.ini.getNumber("SuppressionThreshold"),this.reselectIfLimboed=this.ini.getBool("ReselectIfLimboed"),this.rejoinTeamIfLimboed=this.ini.getBool("RejoinTeamIfLimboed"),this.weight=this.ini.getNumber("Weight"),this.accelerates=this.ini.getBool("Accelerates",!0),this.accelerationFactor=this.ini.getNumber("AccelerationFactor",.03),this.teleporter=this.ini.getBool("Teleporter"),this.canDisguise=this.ini.getBool("CanDisguise"),this.disguiseWhenStill=this.ini.getBool("DisguiseWhenStill"),this.permaDisguise=this.ini.getBool("PermaDisguise"),this.detectDisguise=this.ini.getBool("DetectDisguise"),this.detectDisguiseRange=this.ini.getNumber("DetectDisguiseRange"),this.cloakable=this.ini.getBool("Cloakable"),this.sensors=this.ini.getBool("Sensors"),this.sensorArray=this.ini.getBool("SensorArray"),this.sensorsSight=this.ini.getNumber("SensorsSight"),this.burstDelay=this.parseBurstDelay(),this.vhpScan=this.ini.getEnum("VHPScan",VhpScan,VhpScan.None,!0),this.pip=this.ini.getEnum("Pip",PipColor,PipColor.Green,!0),this.passengers=this.ini.getNumber("Passengers"),this.gunner=this.ini.getBool("Gunner"),this.ammo=this.ini.getNumber("Ammo",-1),this.initialAmmo=this.ini.getNumber("InitialAmmo",-1),this.manualReload=this.ini.getBool("ManualReload",this.type===ObjectType.Aircraft),this.storage=this.ini.getNumber("Storage"),this.spawned=this.ini.getBool("Spawned"),this.spawns=this.ini.getString("Spawns"),this.spawnsNumber=this.ini.getNumber("SpawnsNumber"),this.spawnRegenRate=this.ini.getNumber("SpawnRegenRate"),this.spawnReloadRate=this.ini.getNumber("SpawnReloadRate"),this.missileSpawn=this.ini.getBool("MissileSpawn"),this.size=this.ini.getNumber("Size",1),this.sizeLimit=this.ini.getNumber("SizeLimit"),this.sight=Math.min(TechnoRules.MAX_SIGHT,this.needsEngineer?6:this.ini.getNumber("Sight",1)),this.spySat=this.ini.getBool("SpySat"),this.gapGenerator=this.ini.getBool("GapGenerator"),this.gapRadiusInCells=this.ini.getNumber("GapRadiusInCells"),this.psychicDetectionRadius=this.ini.getNumber("PsychicDetectionRadius"),this.hasRadialIndicator=this.ini.getBool("HasRadialIndicator"),this.harvester=this.ini.getBool("Harvester"),this.unloadingClass=this.ini.getString("UnloadingClass"),this.dock=this.ini.getArray("Dock"),this.radar=this.ini.getBool("Radar"),this.radarInvisible=this.ini.getBool("RadarInvisible"),this.revealToAll=this.ini.getBool("RevealToAll"),this.selectable=!(this.type===ObjectType.Aircraft&&!i)&&this.ini.getBool("Selectable",!0),this.isSelectableCombatant=this.ini.getBool("IsSelectableCombatant"),this.invisibleInGame=this.ini.getBool("InvisibleInGame"),this.moveToShroud=this.ini.getBool("MoveToShroud",this.type!==ObjectType.Aircraft),this.leadershipRating=this.ini.getNumber("LeadershipRating",5),this.unnatural=this.ini.getBool("Unnatural"),this.natural=this.ini.getBool("Natural"),this.buildTimeMultiplier=this.ini.getFixed("BuildTimeMultiplier",1),this.allowedToStartInMultiplayer=this.ini.getBool("AllowedToStartInMultiplayer",!0),this.rot=ObjectRules.iniRotToDegsPerTick(this.ini.getNumber("ROT",0)),this.jumpjetAccel=this.ini.getNumber("JumpJetAccel",2),this.jumpjetClimb=this.ini.getNumber("JumpjetClimb",5),this.jumpjetCrash=this.ini.getNumber("JumpjetCrash",5),this.jumpjetDeviation=this.ini.getNumber("JumpjetDeviation",40),this.jumpjetHeight=this.ini.getNumber("JumpjetHeight",500),this.jumpjetNoWobbles=this.ini.getBool("JumpjetNoWobbles"),this.jumpjetSpeed=this.ini.getNumber("JumpjetSpeed",14),this.jumpjetTurnRate=ObjectRules.iniRotToDegsPerTick(this.ini.getNumber("JumpJetTurnRate",4)),this.jumpjetWobbles=this.ini.getNumber("JumpjetWobbles",.15),this.pitchSpeed=this.ini.getNumber("PitchSpeed",.25),this.pitchAngle=1<=this.pitchSpeed?0:20,this.damageParticleSystems=this.ini.getArray("DamageParticleSystems");i=this.ini.getNumberArray("DamageSmokeOffset",void 0,[0,0,0]);this.damageSmokeOffset=new Vector3_Vector3(i[0],i[2]/Math.SQRT2,i[1]),this.minDebris=this.ini.getNumber("MinDebris"),this.maxDebris=this.ini.getNumber("MaxDebris"),this.debrisTypes=this.ini.getArray("DebrisTypes"),this.debrisAnims=this.ini.getArray("DebrisAnims"),this.isLightpost="GALITE"===this.imageName,this.lightVisibility=this.ini.getNumber("LightVisibility",5e3),this.lightIntensity=this.ini.getNumber("LightIntensity"),this.lightRedTint=this.ini.getNumber("LightRedTint",1),this.lightGreenTint=this.ini.getNumber("LightGreenTint",1),this.lightBlueTint=this.ini.getNumber("LightBlueTint",1),this.ambientSound=this.ini.getString("AmbientSound")||void 0,this.createSound=this.ini.getString("CreateSound")||void 0,this.deploySound=this.ini.getString("DeploySound")||void 0,this.undeploySound=this.ini.getString("UndeploySound")||void 0,this.voiceSelect=this.ini.getString("VoiceSelect")||void 0,this.voiceMove=this.ini.getString("VoiceMove")||void 0,this.voiceAttack=this.ini.getString("VoiceAttack")||void 0,this.voiceFeedback=this.ini.getString("VoiceFeedback")||void 0,this.voiceSpecialAttack=this.ini.getString("VoiceSpecialAttack")||void 0,this.voiceEnter=this.ini.getString("VoiceEnter")||void 0,this.voiceCapture=this.ini.getString("VoiceCapture")||void 0,this.voiceCrashing=this.ini.getString("VoiceCrashing")||void 0,this.crashingSound=this.ini.getString("CrashingSound")||void 0,this.impactLandSound=this.ini.getString("ImpactLandSound")||void 0,this.auxSound1=this.ini.getString("AuxSound1")||void 0,this.auxSound2=this.ini.getString("AuxSound2")||void 0,this.dieSound=this.ini.getString("DieSound")||void 0,this.moveSound=this.ini.getString("MoveSound")||void 0,this.enterWaterSound=this.ini.getString("EnterWaterSound")||void 0,this.leaveWaterSound=this.ini.getString("LeaveWaterSound")||void 0,this.turretRotateSound=this.ini.getString("TurretRotateSound")||void 0,this.workingSound=this.ini.getString("WorkingSound")||void 0,this.notWorkingSound=this.ini.getString("NotWorkingSound")||void 0,this.chronoInSound=this.ini.getString("ChronoInSound")||void 0,this.chronoOutSound=this.ini.getString("ChronoOutSound")||void 0,this.enterTransportSound=this.ini.getString("EnterTransportSound")||void 0,this.leaveTransportSound=this.ini.getString("LeaveTransportSound")||void 0}parseWeaponName(e){return e&&"none"!==e.toLowerCase()?e:void 0}parseTurretIndexes(){let i=new Map;return this.ini.getBool("Gunner")&&this.ini.entries.forEach((e,t)=>{t=t.match(/^(.*)TurretWeapon$/i);t&&(t=t[1]+"TurretIndex",this.ini.has(t)&&i.set(Number(e),this.ini.getNumber(t)))}),i}parseBurstDelay(){let t=[];for(let e=0;e<4;++e)t.push(this.ini.has("BurstDelay"+e)?this.ini.getNumber("BurstDelay"+e):void 0);return t}hasOwner(e){return!!this.owner.length&&-1!==this.owner.indexOf(e.name)}isAvailableTo(e){return(!this.requiredHouses.length||-1!==this.requiredHouses.indexOf(e.name))&&-1===this.forbiddenHouses.indexOf(e.name)}getWeaponAtIndex(e){return this.parseWeaponName(this.ini.getString("Weapon"+(e+1)))}getEliteWeaponAtIndex(e){return this.parseWeaponName(this.ini.getString("EliteWeapon"+(e+1)))}}TechnoRules.MAX_SIGHT=11;class OverlayRules extends ObjectRules{parse(){super.parse(),this.armor=this.ini.getEnum("Armor",ArmorType,ArmorType.None,!0),this.crate=this.ini.getBool("Crate");var e=this.ini.getBool("IsARock");this.isARock=e,this.isRubble=this.ini.getBool("IsRubble"),this.isVeinholeMonster=this.ini.getBool("IsVeinholeMonster"),this.isVeins=this.ini.getBool("IsVeins"),this.land=this.ini.getEnum("Land",LandType,LandType.Clear),this.noUseTileLandType=!!this.ini.getString("NoUseTileLandType"),this.strength=this.ini.getNumber("Strength"),this.tiberium=this.ini.getBool("Tiberium");var t=this.ini.getBool("Wall");this.wall=t,this.radarInvisible=this.ini.getBool("RadarInvisible",!t&&!e)}}function testOccupationBit(e,t){switch(e){case 0:case 1:return!0;case 2:return 0!=(t&OccupationBits.Right);case 3:return 0!=(t&OccupationBits.Left);case 4:return 0!=(t&OccupationBits.Bottom);default:throw new Error('Invalid subCell "'+e)}}!function(e){e[e.All=7]="All",e[e.Right=1]="Right",e[e.Left=2]="Left",e[e.Bottom=4]="Bottom"}(OccupationBits=OccupationBits||{});class TerrainRules extends ObjectRules{parse(){super.parse(),this.animationRate=this.ini.getNumber("AnimationRate"),this.animationProbability=this.ini.getNumber("AnimationProbability"),this.gate=this.ini.getBool("Gate"),this.immune=this.ini.getBool("Immune"),this.isAnimated=this.ini.getBool("IsAnimated"),this.snowOccupationBits=this.normalizeOccupationBits(this.ini.getNumber("SnowOccupationBits",OccupationBits.All)),this.spawnsTiberium=this.ini.getBool("SpawnsTiberium"),this.strength=this.ini.getNumber("Strength"),this.radarInvisible=this.ini.getBool("RadarInvisible"),this.temperateOccupationBits=this.normalizeOccupationBits(this.ini.getNumber("TemperateOccupationBits",OccupationBits.All))}normalizeOccupationBits(e){return(e+8*Math.abs(Math.floor(e/8)))%8}getOccupationBits(e){return e!==TheaterType.Snow?this.temperateOccupationBits:this.snowOccupationBits}getOccupiedSubCells(e){var t,i=this.getOccupationBits(e),e=[0,1,2,3,4];if(i===OccupationBits.All)return e;let r=[];for(t of e)testOccupationBit(t,i)&&r.push(t);return r}}class SmudgeRules extends ObjectRules{parse(){super.parse(),this.burn=this.ini.getBool("Burn"),this.crater=this.ini.getBool("Crater"),this.width=this.ini.getNumber("Width",1),this.height=this.ini.getNumber("Height",1)}}class DebrisRules extends ObjectRules{parse(){super.parse(),this.damage=this.ini.getNumber("Damage"),this.damageRadius=this.ini.getNumber("DamageRadius"),this.duration=this.ini.getNumber("Duration"),this.elasticity=clamp(this.ini.getNumber("Elasticity",.75),0,1),this.expireAnim=this.ini.getString("ExpireAnim")||void 0,this.minAngularVelocity=this.ini.getNumber("MinAngularVelocity"),this.maxAngularVelocity=this.ini.getNumber("MaxAngularVelocity"),this.maxXYVel=this.ini.getNumber("MaxXYVel"),this.minZVel=this.ini.getNumber("MinZVel"),this.maxZVel=this.ini.getNumber("MaxZVel"),this.shareTurretData=this.ini.getBool("ShareTurretData"),this.shareBodyData=this.ini.getBool("ShareBodyData"),this.shareBarrelData=this.ini.getBool("ShareBarrelData"),this.shareSource=this.ini.getString("ShareSource")||void 0,this.trailerAnim=this.ini.getString("TrailerAnim")||void 0,this.trailerSeparation=this.ini.getNumber("TrailerSeperation"),this.warhead=this.ini.getString("Warhead")||void 0}}class ObjectRulesFactory{create(e,t,i,r){switch(e){case ObjectType.Aircraft:case ObjectType.Building:case ObjectType.Infantry:case ObjectType.Vehicle:return new TechnoRules(e,t,r,i);case ObjectType.Overlay:return new OverlayRules(e,t,r);case ObjectType.Terrain:return new TerrainRules(e,t,r);case ObjectType.Smudge:return new SmudgeRules(e,t,r);case ObjectType.VoxelAnim:return new DebrisRules(e,t,r);default:return new ObjectRules(e,t,r)}}}class CombatDamageRules{readIni(e){this.ballisticScatter=e.getNumber("BallisticScatter"),this.bridgeStrength=e.getNumber("BridgeStrength"),this.c4Delay=e.getNumber("C4Delay"),this.c4Warhead=e.getString("C4Warhead"),this.deathWeapon=e.getString("DeathWeapon"),this.dMislEliteWarhead=e.getString("DMislEliteWarhead"),this.dMislWarhead=e.getString("DMislWarhead"),this.flameDamage=e.getString("FlameDamage"),this.ironCurtainDuration=e.getNumber("IronCurtainDuration"),this.ivanDamage=e.getNumber("IvanDamage"),this.ivanIconFlickerRate=e.getNumber("IvanIconFlickerRate"),this.ivanTimedDelay=e.getNumber("IvanTimedDelay"),this.ivanWarhead=e.getString("IvanWarhead"),this.splashList=e.getArray("SplashList"),this.v3EliteWarhead=e.getString("V3EliteWarhead"),this.v3Warhead=e.getString("V3Warhead")}}class TiberiumRules{constructor(e){this.type=e}readIni(e){return this.value=e.getNumber("Value"),this}}class AiRules{readIni(e){this.buildPower=e.getArray("BuildPower"),this.buildRefinery=e.getArray("BuildRefinery"),this.buildTech=e.getArray("BuildTech"),this.tiberiumFarScan=e.getNumber("TiberiumFarScan",50),this.tiberiumNearScan=e.getNumber("TiberiumNearScan",5)}}class ElevationModelRules{readIni(e){return this.increment=e.getNumber("ElevationIncrement"),this.incrementBonus=e.getNumber("ElevationIncrementBonus",1),this.bonusCap=e.getNumber("ElevationBonusCap"),this}getBonus(e,t){return e<=t?0:Math.min(this.bonusCap,Math.floor((e-t)/this.increment))*this.incrementBonus}}class RadiationRules{readIni(e){this.radDurationMultiple=e.getNumber("RadDurationMultiple"),this.radApplicationDelay=e.getNumber("RadApplicationDelay"),this.radLevelMax=e.getNumber("RadLevelMax"),this.radLevelDelay=e.getNumber("RadLevelDelay"),this.radLightDelay=e.getNumber("RadLightDelay"),this.radLevelFactor=e.getNumber("RadLevelFactor"),this.radLightFactor=e.getNumber("RadLightFactor"),this.radTintFactor=e.getNumber("RadTintFactor"),this.radColor=e.getNumberArray("RadColor"),this.radSiteWarhead=e.getString("RadSiteWarhead")}}!function(e){e[e.MultiMissile=0]="MultiMissile",e[e.IronCurtain=1]="IronCurtain",e[e.LightningStorm=2]="LightningStorm",e[e.ChronoSphere=3]="ChronoSphere",e[e.ChronoWarp=4]="ChronoWarp",e[e.ParaDrop=5]="ParaDrop",e[e.AmerParaDrop=6]="AmerParaDrop"}(SuperWeaponType=SuperWeaponType||{});class SuperWeaponRules{constructor(e){this.index=e}readIni(e){return this.disableableFromShell=e.getBool("DisableableFromShell"),this.isPowered=e.getBool("IsPowered",!0),this.name=e.name,this.preClick=e.getBool("PreClick"),this.preDependent=e.getEnum("PreDependent",SuperWeaponType,void 0),this.postClick=e.getBool("PostClick"),this.rechargeTime=e.getNumber("RechargeTime",5),this.showTimer=e.getBool("ShowTimer"),this.sidebarImage=e.getString("SidebarImage").toLowerCase(),this.type=e.getEnum("Type",SuperWeaponType,void 0),this.uiName=e.getString("UIName"),this.weaponType=e.getString("WeaponType")||void 0,this}}class CrateRules{readIni(e){this.crateMaximum=e.getNumber("CrateMaximum"),this.crateMinimum=e.getNumber("CrateMinimum"),this.crateRadius=e.getNumber("CrateRadius"),this.crateRegen=e.getNumber("CrateRegen");let t=e.getString("UnitCrateType");return this.unitCrateType="none"!==t.toLowerCase()?t:void 0,this.healCrateSound=e.getString("HealCrateSound"),this.crateImg=e.getString("CrateImg"),this.waterCrateImg=e.getString("WaterCrateImg"),this.freeMCV=e.getBool("FreeMCV"),this}}!function(e){e[e.Cheer=0]="Cheer",e[e.UnitDeployUndeploy=1]="UnitDeployUndeploy",e[e.WeaponFire=2]="WeaponFire",e[e.ObjectDestroy=3]="ObjectDestroy",e[e.ObjectSpawn=4]="ObjectSpawn",e[e.ObjectUnspawn=5]="ObjectUnspawn",e[e.ObjectMorph=6]="ObjectMorph",e[e.ObjectLiftOff=7]="ObjectLiftOff",e[e.ObjectLand=8]="ObjectLand",e[e.ObjectCrashing=9]="ObjectCrashing",e[e.ObjectDisguiseChange=10]="ObjectDisguiseChange",e[e.ObjectCloakChange=11]="ObjectCloakChange",e[e.ObjectAttacked=12]="ObjectAttacked",e[e.ShipSubmergeChange=13]="ShipSubmergeChange",e[e.BridgeRepair=14]="BridgeRepair",e[e.BuildStatusChange=15]="BuildStatusChange",e[e.BuildingPlace=16]="BuildingPlace",e[e.BuildingFailedPlace=17]="BuildingFailedPlace",e[e.ObjectSell=18]="ObjectSell",e[e.BuildingRepairFull=19]="BuildingRepairFull",e[e.BuildingCapture=20]="BuildingCapture",e[e.BuildingInfiltration=21]="BuildingInfiltration",e[e.BuildingGarrison=22]="BuildingGarrison",e[e.BuildingEvacuate=23]="BuildingEvacuate",e[e.BuildingRepairStart=24]="BuildingRepairStart",e[e.UnitRepairStart=25]="UnitRepairStart",e[e.UnitRepairFinish=26]="UnitRepairFinish",e[e.UnitRecycle=27]="UnitRecycle",e[e.InflictDamage=28]="InflictDamage",e[e.HealthChange=29]="HealthChange",e[e.WarheadDetonate=30]="WarheadDetonate",e[e.PlayerDefeated=31]="PlayerDefeated",e[e.PlayerResigned=32]="PlayerResigned",e[e.PlayerDropped=33]="PlayerDropped",e[e.DeployNotAllowed=34]="DeployNotAllowed",e[e.PowerChange=35]="PowerChange",e[e.PowerLow=36]="PowerLow",e[e.PowerRestore=37]="PowerRestore",e[e.RadarOnOff=38]="RadarOnOff",e[e.ObjectOwnerChange=39]="ObjectOwnerChange",e[e.RadarEvent=40]="RadarEvent",e[e.InsufficientFunds=41]="InsufficientFunds",e[e.RallyPointChange=42]="RallyPointChange",e[e.PrimaryFactoryChange=43]="PrimaryFactoryChange",e[e.FactoryProduceUnit=44]="FactoryProduceUnit",e[e.ObjectTeleport=45]="ObjectTeleport",e[e.AllianceChange=46]="AllianceChange",e[e.UnitPromote=47]="UnitPromote",e[e.EnterTransport=48]="EnterTransport",e[e.LeaveTransport=49]="LeaveTransport",e[e.EnterObject=50]="EnterObject",e[e.EnterTile=51]="EnterTile",e[e.SuperWeaponReady=52]="SuperWeaponReady",e[e.SuperWeaponActivate=53]="SuperWeaponActivate",e[e.LightningStormManifest=54]="LightningStormManifest",e[e.LightningStormCloud=55]="LightningStormCloud",e[e.CratePickup=56]="CratePickup",e[e.PingLocation=57]="PingLocation",e[e.StalemateDetect=58]="StalemateDetect",e[e.TriggerSoundFx=59]="TriggerSoundFx",e[e.TriggerStopSoundFx=60]="TriggerStopSoundFx",e[e.TriggerEva=61]="TriggerEva",e[e.TriggerAnim=62]="TriggerAnim",e[e.TriggerText=63]="TriggerText",e[e.TimerExpire=64]="TimerExpire"}(EventType=EventType||{});class CratePickupEvent{constructor(e,t,i,r){this.target=e,this.player=t,this.source=i,this.tile=r,this.type=EventType.CratePickup}}function getZoneType(e){return[LandType.Water,LandType.Beach].includes(e)?ZoneType.Water:ZoneType.Ground}!function(e){e[e.Ground=0]="Ground",e[e.Air=1]="Air",e[e.Water=2]="Water"}(ZoneType=ZoneType||{});const isGameObject=e=>void 0!==e.position,isVector3=e=>void 0!==e.addScalar;class RangeHelper{constructor(e){this.tileOccupation=e}isInWeaponRange(e,t,i,r,s){var a=s??e;if(i.rules.limboLaunch&&2<Math.abs((isGameObject(a)?a.position.tileElevation+a.tile.z:a.z)-(isGameObject(t)?t.position.tileElevation+t.tile.z:t.z)))return!1;var{minRange:s,range:r}=this.computeWeaponRangeVsTarget(a,t,i,r);return i.rules.cellRangefinding?this.isInTileRange(a,t,s,r):e.isUnit()&&e.rules.movementZone===MovementZone.Fly?this.isInRange2(a,t,s,r):this.isInRange3(a,t,s,r)}computeWeaponRangeVsTarget(e,t,i,r){let s=0;var a,n;return isGameObject(t)&&t.isBuilding()&&!i.projectileRules.arcing&&!i.projectileRules.vertical&&(n=t.getFoundation(),i.warhead.rules.ivanBomb&&2<n.width+n.height||(s+=(n.width+n.height)/4)),!i.projectileRules.subjectToElevation||i.projectileRules.arcing&&!isGameObject(t)||(a=isGameObject(e)?e.tile.z+e.tileElevation:e.z,(n=isGameObject(t)?t.tile.z+t.tileElevation:t.z)<a&&(s+=r.elevationModel.getBonus(a,n))),i.projectileRules.isAntiAir&&isGameObject(e)&&e.isTechno()&&isGameObject(t)&&t.isUnit()&&t.zone===ZoneType.Air&&(s+=e.rules.airRangeBonus),{minRange:i.minRange,range:i.range+s}}isInRange(e,t,i,r,s=!1){return s?this.isInTileRange(e,t,i,r):e.isUnit()&&e.rules.movementZone===MovementZone.Fly?this.isInRange2(e,t,i,r):this.isInRange3(e,t,i,r)}isInRange3(e,t,i,r){return isBetween(this.distance3(e,t)/Coords.LEPTONS_PER_TILE,i,r)}isInRange2(e,t,i,r){return isBetween(this.distance2(e,t)/Coords.LEPTONS_PER_TILE,i,r)}distance3(e,t){let i=isGameObject(e)?e.position.worldPosition:isVector3(e)?e:Coords.tile3dToWorld(e.rx+.5,e.ry+.5,e.z);t=isGameObject(t)?t.position.worldPosition:isVector3(t)?t:Coords.tile3dToWorld(t.rx+.5,t.ry+.5,t.z);return i.distanceTo(t)}distance2(e,t){let i=isGameObject(e)?new Vector2(e.position.worldPosition.x,e.position.worldPosition.z):isVector3(e)?new Vector2(e.x,e.z):new Vector2(e.rx+.5,e.ry+.5).multiplyScalar(Coords.LEPTONS_PER_TILE);t=isGameObject(t)?new Vector2(t.position.worldPosition.x,t.position.worldPosition.z):isVector3(t)?new Vector2(t.x,t.z):new Vector2(t.rx+.5,t.ry+.5).multiplyScalar(Coords.LEPTONS_PER_TILE);return i.distanceTo(t)}isInTileRange(e,t,i,r){let s;var a;return s=!Array.isArray(e)&&isGameObject(t)&&t.isUnit()?(a=isGameObject(e)?e.tile:e,new Vector2(a.rx+.5,a.ry+.5).distanceTo(t.position.getMapPosition().multiplyScalar(1/Coords.LEPTONS_PER_TILE))):this.tileDistance(e,t),isBetween(s,i,r)}tileDistance(e,t){var i,e=isGameObject(e)?this.tileOccupation.calculateTilesForGameObject(e.tile,e):Array.isArray(e)?e:[e],r=isGameObject(t)?this.tileOccupation.calculateTilesForGameObject(t.tile,t):Array.isArray(t)?t:[t];let s=new Vector2,a=new Vector2,n=Number.POSITIVE_INFINITY;for(i of e)for(var o of r){s.set(i.rx,i.ry),a.set(o.rx,o.ry);o=s.distanceTo(a);o<=n&&(n=o)}return n}}const isHumanPlayerInfo=e=>"name"in e;!function(e){e[e.Brutal=0]="Brutal",e[e.Medium=1]="Medium",e[e.Easy=2]="Easy"}(AiDifficulty=AiDifficulty||{});const RANDOM_COUNTRY_ID=-2,RANDOM_COLOR_ID=-2,RANDOM_START_POS=-2,NO_TEAM_ID=-2,OBS_COUNTRY_ID=-3,OBS_COLOR_ID=-2,RANDOM_COUNTRY_NAME="Random",OBS_COUNTRY_NAME="Observer",aiUiNames=(new Map).set(AiDifficulty.Easy,"GUI:AIDummy").set(AiDifficulty.Medium,"GUI:AIEasyBeta"),aiUiTooltips=new Map,RANDOM_COUNTRY_UI_NAME="GUI:RandomEx",RANDOM_COUNTRY_UI_TOOLTIP="STT:PlayerSideRandom",OBS_COUNTRY_UI_NAME="GUI:Observer",OBS_COUNTRY_UI_TOOLTIP="STT:PlayerSideObserver",RANDOM_COLOR_NAME="";class GameSpeed{static computeGameSpeed(e){let t;return t=6===e?60:5===e?45:60/(6-e),t/GameSpeed.BASE_TICKS_PER_SECOND}}GameSpeed.BASE_TICKS_PER_SECOND=15;class RadialTileFinder{constructor(e,t,i,r,s,a,n,o=!0){this.tiles=e,this.mapBounds=t,this.startTile=i,this.foundation=r,this.maxDistance=a,this.predicate=n,this.checkBounds=o,this.distance=s,this.generator=this.generate()}getNextTile(){return this.generator.next().value}*generate(){var r=(e,t)=>{t=this.tiles.getByMapCoords(e,t);if(t&&(!this.checkBounds||this.mapBounds.isWithinBounds(t))&&this.predicate(t))return t};do{var s=this.startTile.rx-this.distance,a=this.startTile.ry-this.distance,n=this.startTile.rx+this.foundation.width-1+this.distance,o=this.startTile.ry+this.foundation.height-1+this.distance;let e,t,i;if(0<this.distance){for(e=n;e>=s;e--)i=r(e,o),i&&(yield i);for(t=o-1;t>=a;t--)i=r(n,t),i&&(yield i);for(e=s;e<n;e++)i=r(e,a),i&&(yield i);for(t=1+a;t<o;t++)i=r(s,t),i&&(yield i)}else this.predicate(this.startTile)&&(yield this.startTile)}while(this.distance++,this.distance<=this.maxDistance)}}!function(e){e[e.Armor=0]="Armor",e[e.Firepower=1]="Firepower",e[e.HealBase=2]="HealBase",e[e.Money=3]="Money",e[e.Reveal=4]="Reveal",e[e.Speed=5]="Speed",e[e.Veteran=6]="Veteran",e[e.Unit=7]="Unit",e[e.Invulnerability=8]="Invulnerability",e[e.IonStorm=9]="IonStorm",e[e.Gas=10]="Gas",e[e.Tiberium=11]="Tiberium",e[e.Pod=12]="Pod",e[e.Cloak=13]="Cloak",e[e.Darkness=14]="Darkness",e[e.Explosion=15]="Explosion",e[e.ICBM=16]="ICBM",e[e.Napalm=17]="Napalm",e[e.Squad=18]="Squad"}(PowerupType=PowerupType||{}),(NotifyTick=NotifyTick||{}).onTick=Symbol(),(NotifyWarpChange=NotifyWarpChange||{}).onChange=Symbol();class SuperWeaponReadyEvent{constructor(e){this.target=e,this.type=EventType.SuperWeaponReady}}!function(e){e[e.Charging=0]="Charging",e[e.Paused=1]="Paused",e[e.Ready=2]="Ready"}(SuperWeaponStatus=SuperWeaponStatus||{});class SuperWeapon{constructor(e,t,i,r=!1){this.name=e,this.rules=t,this.owner=i,this.oneTimeOnly=r,this.status=SuperWeaponStatus.Charging,this.isGift=!1,this.rechargeTicks=60*t.rechargeTime*GameSpeed.BASE_TICKS_PER_SECOND,this.chargeTicks=this.rechargeTicks,r&&(this.status=SuperWeaponStatus.Ready,this.chargeTicks=0)}update(e){0<this.chargeTicks&&this.status!==SuperWeaponStatus.Paused&&(this.chargeTicks--,0===this.chargeTicks&&(this.status=SuperWeaponStatus.Ready,e.events.dispatch(new SuperWeaponReadyEvent(this))))}pauseTimer(){this.status=SuperWeaponStatus.Paused}resumeTimer(){this.status=0<this.chargeTicks?SuperWeaponStatus.Charging:SuperWeaponStatus.Ready}resetTimer(){this.chargeTicks=this.rechargeTicks,this.status===SuperWeaponStatus.Ready&&(this.status=SuperWeaponStatus.Charging)}getTimerSeconds(){return this.chargeTicks/GameSpeed.BASE_TICKS_PER_SECOND}getChargeProgress(){return(this.rechargeTicks-this.chargeTicks)/this.rechargeTicks}}!function(e){e[e.NotStarted=0]="NotStarted",e[e.Running=1]="Running",e[e.Finished=2]="Finished"}(EffectStatus=EffectStatus||{});class SuperWeaponEffect{constructor(e,t,i){this.type=e,this.owner=t,this.tile=i,this.status=EffectStatus.NotStarted}onStart(e){}onTick(e){return!0}}!function(e){e.onPowerLow=Symbol(),e.onPowerRestore=Symbol(),e.onPowerChange=Symbol()}(NotifyPower=NotifyPower||{}),(NotifySuperWeaponActivate=NotifySuperWeaponActivate||{}).onActivate=Symbol();class SuperWeaponActivateEvent{constructor(e,t,i,r,s){this.target=e,this.owner=t,this.atTile=i,this.atTile2=r,this.noSfxWarning=s,this.type=EventType.SuperWeaponActivate}}!function(e){e[e.None=0]="None",e[e.Guard=1]="Guard",e[e.Prone=2]="Prone",e[e.Deployed=3]="Deployed",e[e.Paradrop=4]="Paradrop",e[e.Cheer=5]="Cheer"}(StanceType=StanceType||{}),function(e){e[e.NotStarted=0]="NotStarted",e[e.Running=1]="Running",e[e.Finished=2]="Finished",e[e.Cancelling=3]="Cancelling",e[e.Cancelled=4]="Cancelled"}(TaskStatus=TaskStatus||{});class Task{constructor(){this.status=TaskStatus.NotStarted,this.children=[],this.cancellable=!0,this.useChildTargetLines=!1,this.blocking=!0,this.waitingForChildrenToFinish=!1,this.preventOpportunityFire=!0,this.preventLanding=!0,this.isAttackMove=!1}isRunning(){return this.status===TaskStatus.Running}isCancelling(){return this.status===TaskStatus.Cancelling}setCancellable(e){return this.cancellable=e,this}setBlocking(e){return this.blocking=e,this}onStart(e){}onEnd(e){}cancel(){if(this.cancellable)if(this.status===TaskStatus.Running)this.status=TaskStatus.Cancelling,this.children.length&&this.children.forEach(e=>e.cancel());else if(this.status===TaskStatus.NotStarted&&(this.status=TaskStatus.Cancelled,this.children.length))throw new Error("Should't have any children before starting a task")}getTargetLinesConfig(e){}}function findReverse(t,i){for(let e=t.length-1;0<=e;e--)if(i(t[e],e,t))return t[e]}function findIndexReverse(t,i){for(let e=t.length-1;0<=e;e--)if(i(t[e],e,t))return e;return-1}function equals(i,r){if(i.length!==r.length)return!1;for(let e=0,t=i.length;e<t;e++)if(i[e]!==r[e])return!1;return!0}class WaitTicksTask extends Task{constructor(e){super(),this.ticks=e}onTick(){return!!this.isCancelling()||!(0<this.ticks--)}}class MovePositionHelper{constructor(e){this.map=e}findPositions(e,r,s,a){let n=new Map,t=this.clusterObjects(e);if(!t.length)throw new Error("We should have found at least one cluster");let i=t.reduce((e,t)=>t.objects.size>e.objects.size?t:e,t[0]);t.splice(t.indexOf(i),1);let o=[],l=this.findCenterTile([...i.objects]);i.objects.forEach(t=>{var i=this.map.tiles.getByMapCoords(r.rx+t.tile.rx-l.rx,r.ry+t.tile.ry-l.ry),e=i?.onBridgeLandType?this.map.tileOccupation.getBridgeOnTile(i):void 0;if(!this.shouldStackObject(t)&&i&&this.map.mapBounds.isWithinBounds(i)&&this.tileHasRoom(i,t,n.get(i))&&(t.rules.movementZone===MovementZone.Fly?t.rules.airportBound||a&&t.rules.balloonHover&&!t.rules.hoverAttack||this.map.terrain.getPassableSpeed(i,SpeedType.Amphibious,!1,!!e):this.isEligibleTile(i,e,s,r))){let e=n.get(i);void 0===e&&(e=[],n.set(i,e)),e.push(t)}else o.push(t)}),t.forEach(e=>o.push(...e.objects));let h=new RadialTileFinder(this.map.tiles,this.map.mapBounds,r,{width:1,height:1},0,5,()=>!0),c=h.getNextTile();for(;o.length&&c;){var u=o[0],d=this.map.tileOccupation.getBridgeOnTile(c);if(this.tileHasRoom(c,u,n.get(c))&&(u.rules.movementZone===MovementZone.Fly?u.rules.airportBound||this.map.terrain.getPassableSpeed(c,SpeedType.Amphibious,!1,!!d):this.isEligibleTile(c,d,s,r))){let e=n.get(c);void 0===e&&(e=[],n.set(c,e)),e.push(o.shift())}else c=h.getNextTile()}let p=new Map;if(n.forEach((e,t)=>{e.forEach(e=>p.set(e,t))}),o.forEach(e=>p.set(e,r)),p.size!==e.length)throw new Error("We should have computed a number of positions equal to the number of input objects");return p}shouldStackObject(e){return e.isBuilding()||e.isUnit()&&e.moveTrait.isMoving()&&e.rules.movementZone===MovementZone.Fly&&e.rules.locomotor===LocomotorType.Jumpjet}tileHasRoom(e,t,i){if(t.isBuilding())return!!t.rules.undeploysInto||!this.map.tileOccupation.getGroundObjectsOnTile(e).some(e=>e.isTerrain()||e.isTechno()||e.isOverlay()&&e.wallTrait);if(!i)return!0;if(this.shouldStackObject(t))return i.length<3;if(t.isInfantry()){if(i.find(e=>!e.isInfantry()))return!1;t=t.rules.movementZone===MovementZone.Fly?1:3;return i.filter(e=>e.isInfantry()).length>=t?!1:!0}return!i.length}isEligibleTile(e,t,i,r){return i?.isHighBridge()||t?.isHighBridge()?e.z+(t?.tileElevation??0)===r.z+(i?.tileElevation??0):!(!i&&!t)||Math.abs(e.z-r.z)<2}clusterObjects(e){let s=new Map;e.forEach(e=>{var t=e.tile.rx+"_"+e.tile.ry;s.set(t,[...s.get(t)||[],e])});let t=[],a=new Set(e);for(;a.size;){let e=new Set,r=[];var i=[...a][0].tile;for(s.get(i.rx+"_"+i.ry).forEach(e=>{r.push(e)});r.length;){var n=r.shift();e.add(n),a.delete(n);for(let i=-1;i<=1;i++)for(let t=-1;t<=1;t++)if(i||t){let e=s.get(n.tile.rx+i+"_"+(n.tile.ry+t));e&&e.length&&e.forEach(e=>{a.has(e)&&(a.delete(e),r.push(e))})}}t.push({objects:e})}return t}findCenterTile(e){let t=0,i=0;e.forEach(e=>{t+=e.tile.rx,i+=e.tile.ry}),t=Math.round(t/e.length),i=Math.round(i/e.length);let r=this.map.tiles.getByMapCoords(t,i);if(!r&&(r=e.find(e=>Math.abs(e.tile.rx-t)<=1&&Math.abs(e.tile.ry-i)<=1)?.tile,!r))throw new Error("At least one adjacent object should have been found");return r}}var Matrix4_THREE=__webpack_require__(70);class Matrix4 extends Matrix4_THREE.Matrix4{extractRotation(e){let t=this.elements;var i=e.elements,r=1/_vector3.setFromMatrixColumn(e,0).length(),s=1/_vector3.setFromMatrixColumn(e,1).length(),e=1/_vector3.setFromMatrixColumn(e,2).length();return t[0]=i[0]*r,t[1]=i[1]*r,t[2]=i[2]*r,t[3]=0,t[4]=i[4]*s,t[5]=i[5]*s,t[6]=i[6]*s,t[7]=0,t[8]=i[8]*e,t[9]=i[9]*e,t[10]=i[10]*e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,this}makeRotationFromEuler(e){e&&e.isEuler||console.error("THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.");let t=this.elements;var i,r,s,a,n,o,l,h,c,u,d,p=e.x,g=e.y,m=e.z,y=GameMath.cos(p),T=GameMath.sin(p),f=GameMath.cos(g),v=GameMath.sin(g),p=GameMath.cos(m),g=GameMath.sin(m);return"XYZ"===e.order?(i=y*p,s=y*g,r=T*p,m=T*g,t[0]=f*p,t[4]=-f*g,t[8]=v,t[1]=s+r*v,t[5]=i-m*v,t[9]=-T*f,t[2]=m-i*v,t[6]=r+s*v,t[10]=y*f):"YXZ"===e.order?(a=f*p,i=f*g,r=v*p,s=v*g,t[0]=a+s*T,t[4]=r*T-i,t[8]=y*v,t[1]=y*g,t[5]=y*p,t[9]=-T,t[2]=i*T-r,t[6]=s+a*T,t[10]=y*f):"ZXY"===e.order?(l=f*p,a=f*g,n=v*p,o=v*g,t[0]=l-o*T,t[4]=-y*g,t[8]=n+a*T,t[1]=a+n*T,t[5]=y*p,t[9]=o-l*T,t[2]=-y*v,t[6]=T,t[10]=y*f):"ZYX"===e.order?(n=y*p,o=y*g,h=T*p,l=T*g,t[0]=f*p,t[4]=h*v-o,t[8]=n*v+l,t[1]=f*g,t[5]=l*v+n,t[9]=o*v-h,t[2]=-v,t[6]=T*f,t[10]=y*f):"YZX"===e.order?(u=y*f,h=y*v,c=T*f,d=T*v,t[0]=f*p,t[4]=d-u*g,t[8]=c*g+h,t[1]=g,t[5]=y*p,t[9]=-T*p,t[2]=-v*p,t[6]=h*g+c,t[10]=u-d*g):"XZY"===e.order&&(c=y*f,u=y*v,d=T*f,e=T*v,t[0]=f*p,t[4]=-g,t[8]=v*p,t[1]=c*g+e,t[5]=y*p,t[9]=u*g-d,t[2]=d*g-u,t[6]=T*p,t[10]=e*g+c),t[3]=0,t[7]=0,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,this}lookAt(e,t,i){_x.set(0,0,0),_y.set(0,0,0),_z.set(0,0,0);const r=this.elements;return _z.subVectors(e,t),0===_z.lengthSq()&&(_z.z=1),_z.normalize(),_x.crossVectors(i,_z),0===_x.lengthSq()&&(1===Math.abs(i.z)?_z.x+=1e-4:_z.z+=1e-4,_z.normalize(),_x.crossVectors(i,_z)),_x.normalize(),_y.crossVectors(_z,_x),r[0]=_x.x,r[4]=_y.x,r[8]=_z.x,r[1]=_x.y,r[5]=_y.y,r[9]=_z.y,r[2]=_x.z,r[6]=_y.z,r[10]=_z.z,this}getMaxScaleOnAxis(){var e=this.elements,t=e[0]*e[0]+e[1]*e[1]+e[2]*e[2],i=e[4]*e[4]+e[5]*e[5]+e[6]*e[6],e=e[8]*e[8]+e[9]*e[9]+e[10]*e[10];return GameMath.sqrt(Math.max(t,i,e))}makeRotationX(e){var t=GameMath.cos(e),e=GameMath.sin(e);return this.set(1,0,0,0,0,t,-e,0,0,e,t,0,0,0,0,1),this}makeRotationY(e){var t=GameMath.cos(e),e=GameMath.sin(e);return this.set(t,0,e,0,0,1,0,0,-e,0,t,0,0,0,0,1),this}makeRotationZ(e){var t=GameMath.cos(e),e=GameMath.sin(e);return this.set(t,-e,0,0,e,t,0,0,0,0,1,0,0,0,0,1),this}makeRotationAxis(e,t){var i=GameMath.cos(t),r=GameMath.sin(t),s=1-i,a=e.x,n=e.y,o=e.z,t=s*a,e=s*n;return this.set(t*a+i,t*n-r*o,t*o+r*n,0,t*n+r*o,e*n+i,e*o-r*a,0,t*o-r*n,e*o+r*a,s*o*o+i,0,0,0,0,1),this}decompose(e,t,i){var r=this.elements;let s=_vector3.set(r[0],r[1],r[2]).length();var a=_vector3.set(r[4],r[5],r[6]).length(),n=_vector3.set(r[8],r[9],r[10]).length();this.determinant()<0&&(s=-s),e.x=r[12],e.y=r[13],e.z=r[14],_matrix.copy(this);var o=1/s,e=1/a,r=1/n;return _matrix.elements[0]*=o,_matrix.elements[1]*=o,_matrix.elements[2]*=o,_matrix.elements[4]*=e,_matrix.elements[5]*=e,_matrix.elements[6]*=e,_matrix.elements[8]*=r,_matrix.elements[9]*=r,_matrix.elements[10]*=r,t.setFromRotationMatrix(_matrix),i.x=s,i.y=a,i.z=n,this}}const _vector3=new Vector3_Vector3,_x=new Vector3_Vector3,_y=new Vector3_Vector3,_z=new Vector3_Vector3,_matrix=new Matrix4;var geometry_THREE=__webpack_require__(70);function radToDeg(e){return e*geometry_THREE.Math.RAD2DEG}function degToRad(e){return e*geometry_THREE.Math.DEG2RAD}const zeroVec=new Vector2;function rotateVec2(e,t){t=degToRad(Math.floor(t));return e.rotateAround(zeroVec,t)}function angleDegFromVec2(e){return Math.round(radToDeg(e.angle()))}function angleDegBetweenQuaternions(e,t){t=radToDeg(2*GameMath.acos(Math.abs(clamp(e.dot(t),-1,1))));return Math.round(t)}function angleDegBetweenVec2(e,t){e=angleDegFromVec2(e),t=angleDegFromVec2(t);return Math.min((e-t+360)%360,(t-e+360)%360)}function angleDegBetweenVec3(e,t){return angleDegBetweenQuaternions(quaternionFromVec3(e,_q1),quaternionFromVec3(t,_q2))}function quaternionFromVec3(e,t=new Quaternion){return t.setFromRotationMatrix(_m4.lookAt(e,_zeroVec3,_upVec3))}const _m4=new Matrix4,_zeroVec3=new Vector3_Vector3(0,0,0),_upVec3=new Vector3_Vector3(0,1,0);function rotateVec3Towards(e,t,i){var r=e.length(),s=quaternionFromVec3(t,_q1),t=quaternionFromVec3(e,_q2);rotateTowards(t,s,i),e.set(0,0,1).applyQuaternion(t).setLength(r)}const _q1=new Quaternion,_q2=new Quaternion;function rotateTowards(e,t,i){var r=angleDegBetweenQuaternions(e,t);if(0!==r){r=Math.min(1,i/r);return e.slerp(t,r)}}const BAILOUT_TICKS=200,RETRY_TICKS=5;class MoveAsideTask extends Task{constructor(e,t){super(),this.game=e,this.fromDirection=t,this.resolved=!1,this.chainPushIssued=!1}onEnd(e){e.moveTrait.collisionState=CollisionState.Resolved}onTick(i){if(this.timeoutTicks=void 0===this.timeoutTicks?0:this.timeoutTicks+1,this.timeoutTicks>BAILOUT_TICKS/RETRY_TICKS||this.resolved||this.isCancelling())return!0;let r=this.game.map,t=new MovePositionHelper(r);var s=i.onBridge?r.tileOccupation.getBridgeOnTile(i.tile):void 0;let a,n;for(let e=0;e<360;e+=45)if((0!==e||this.chainPushIssued)&&180!==e){var o=rotateVec2(this.fromDirection.clone(),e).round(),o=r.tiles.getByMapCoords(i.tile.rx+Math.sign(o.x),i.tile.ry+Math.sign(o.y));if(o&&r.mapBounds.isWithinBounds(o)&&(n=r.tileOccupation.getBridgeOnTile(o),i.rules.movementZone===MovementZone.Fly||!r.terrain.findObstacles({tile:o,onBridge:n},i).length&&t.isEligibleTile(o,n,s,i.tile))){a=o;break}}if(a)return this.resolved=!0,i.isInfantry()&&i.deployerTrait&&i.deployerTrait.isDeployed()&&i.deployerTrait.setDeployed(!1),!!i.moveTrait.isDisabled()||(this.children.push(new MoveTask(this.game,a,!!n,{closeEnoughTiles:0,strictCloseEnough:!0})),!1);{if(this.chainPushIssued)return this.children.push(new WaitTicksTask(RETRY_TICKS)),!1;let t=r.tiles.getByMapCoords(i.tile.rx+Math.sign(this.fromDirection.x),i.tile.ry+Math.sign(this.fromDirection.y));if(!t||!r.mapBounds.isWithinBounds(t))return!0;n=r.tileOccupation.getBridgeOnTile(t);let e=r.tileOccupation.getGroundObjectsOnTile(t).filter(e=>e.isUnit()&&e.owner===i.owner&&e.tile===t&&e.onBridge===!!n&&!(e.isInfantry()&&e.stance===StanceType.Paradrop)&&!(e.isAircraft()&&e.missileSpawnTrait));return e.find(e=>e.moveTrait.collisionState===CollisionState.Waiting||e.unitOrderTrait.hasTasks())?(this.children.push(new WaitTicksTask(RETRY_TICKS)),i.moveTrait.collisionState=CollisionState.Waiting,i.moveTrait.moveState=MoveState.PlanMove,!1):(e.forEach(e=>{e.unitOrderTrait.addTask(new MoveAsideTask(this.game,this.fromDirection))}),this.children.push(new WaitTicksTask(1)),i.moveTrait.collisionState=CollisionState.Waiting,i.moveTrait.moveState=MoveState.PlanMove,!(this.chainPushIssued=!0))}}}var logger=__webpack_require__(370);const AppLogger=logger;class ChronoLocomotor{constructor(e){this.game=e,this.ignoresTerrain=!0,this.distanceToWaypoint=new Vector2}onNewWaypoint(e,t){}tick(e,t,i,r){if(r)return{distance:new Vector3_Vector3,done:!0};this.distanceToWaypoint.copy(t).sub(e.position.getMapPosition());r=this.game.rules.general;return r.chronoTrigger&&(r=(t=this.distanceToWaypoint.length())<r.chronoRangeMinimum?r.chronoMinimumDelay:t/r.chronoDistanceFactor,e.warpedOutTrait.setTimed(r,!1,this.game)),{distance:new Vector3_Vector3(this.distanceToWaypoint.x,0,this.distanceToWaypoint.y),done:!0,isTeleport:!0}}}class FacingUtil{static tick(e,t,i){if(e===t)return{facing:e,delta:0};var r=(e-t+360)%360,s=(t-e+360)%360;if(Math.min(r,s)<i)return{facing:t,delta:0};i*=s<=r?1:-1;return{facing:(e+i+360)%360,delta:i}}static fromMapCoords(e){return(-angleDegFromVec2(e)-90+720)%360}static toMapCoords(e){return rotateVec2(new Vector2(1e3,0),FacingUtil.toWorldDeg(e)).round().normalize()}static toWorldDeg(e){return-(e+90)}}class TurnTask extends Task{constructor(e){super(),this.direction=e,this.cancellable=!1}onTick(e){if(e.direction===this.direction)return!(e.spinVelocity=0);var t=e.rules.rot,{facing:i,delta:t}=FacingUtil.tick(e.direction,this.direction,t);return e.direction=i,e.spinVelocity=t,!1}}var LineCurve_THREE=__webpack_require__(70);class LineCurve extends LineCurve_THREE.LineCurve{constructor(e,t){super(e||new Vector2,t||new Vector2)}getPoint(e,t){return super.getPoint(e,t||new Vector2)}}var CurvePath_THREE=__webpack_require__(70);class CurvePath extends CurvePath_THREE.CurvePath{closePath(){let e=this.curves[0].getPoint(0);var t=this.curves[this.curves.length-1].getPoint(1);e.equals(t)||this.curves.push(new LineCurve(t,e))}}var WaypointType,HoverLocomotor_WaypointType,QuadraticBezierCurve_THREE=__webpack_require__(70);class QuadraticBezierCurve extends QuadraticBezierCurve_THREE.QuadraticBezierCurve{constructor(e,t,i){super(e||new Vector2,t||new Vector2,i||new Vector2)}getPoint(e,t){return super.getPoint(e,t||new Vector2)}}!function(e){e[e.None=0]="None",e[e.Start=1]="Start",e[e.Normal=2]="Normal",e[e.End=3]="End",e[e.Single=4]="Single"}(WaypointType=WaypointType||{});class DriveLocomotor{constructor(e){this.game=e,this.hasMomentum=!1,this.moveOnCurve=!1,this.currentSpeed=0,this.distanceTravelled=0,this.carryOverDistance=0,this.currentWaypointType=WaypointType.None}selectNextWaypoint(i,r){if(this.currentWaypointType=this.currentWaypointType&&this.currentWaypointType!==WaypointType.End?WaypointType.Normal:WaypointType.Start,this.initialPosition=i.position.getMapPosition(),this.currentWaypointType!==WaypointType.Start?i.moveTrait.speedPenalty=0:this.currentSpeed=0,1<r.length){var s=r[r.length-1],a=r[r.length-2],e=new Vector2(s.tile.rx-i.tile.rx,s.tile.ry-i.tile.ry),n=Math.abs(angleDegFromVec2(e)-angleDegFromVec2(new Vector2(a.tile.rx-s.tile.rx,a.tile.ry-s.tile.ry)));if(!Math.abs(FacingUtil.fromMapCoords(e)-i.direction)&&0<n&&n<90&&this.hasMomentum){this.moveOnCurve=!0,this.currentWaypointType=2===r.length?this.currentWaypointType===WaypointType.Start?WaypointType.Single:WaypointType.End:WaypointType.Normal;let e=this.initialPosition;i=new Vector2(s.tile.rx+.5,s.tile.ry+.5).multiplyScalar(Coords.LEPTONS_PER_TILE);let t=new Vector2(a.tile.rx+.5,a.tile.ry+.5).multiplyScalar(Coords.LEPTONS_PER_TILE);n=e.clone().lerp(i,.5),s=t.clone().lerp(i,.5);return this.steerCurve=new CurvePath,this.steerCurve.add(new LineCurve(e,n)),this.steerCurve.add(new QuadraticBezierCurve(n,i,s)),this.steerCurve.add(new LineCurve(s,t)),this.lastPosition=e,a}}else this.currentWaypointType=this.currentWaypointType===WaypointType.Start?WaypointType.Single:WaypointType.End;return this.hasMomentum=!0,this.moveOnCurve=!1,r[r.length-1]}onNewWaypoint(e,t,i){let r=(new Vector2).copy(t).sub(this.initialPosition);this.distanceTravelled=0,this.totalDistanceToTravel=this.moveOnCurve?this.steerCurve.getLength():r.length();t=FacingUtil.fromMapCoords(r);if(t!==e.direction&&(this.pointTurretToTarget(e,i),!this.moveOnCurve))return e.moveTrait.velocity.set(0,0,0),[new TurnTask(t)]}tick(i,r,s){this.pointTurretToTarget(i,s);let a=this.currentSpeed;a=i.rules.accelerates?(l=this.distanceTravelled/this.totalDistanceToTravel,this.currentSpeed=this.applyAcceleration(i,a,i.moveTrait.baseSpeed,l)):this.currentSpeed=i.moveTrait.baseSpeed,1<a&&(a=Math.floor(a));let e=this.game.map.terrain.getPassableSpeed(i.tile,i.rules.speedType,i.isInfantry(),i.onBridge,void 0,!0);e?i.moveTrait.lastTileSpeed=e:e=i.moveTrait.lastTileSpeed||1,a*=e,1<a&&(a=Math.floor(a)),this.carryOverDistance&&(a=this.carryOverDistance);var n=i.position.getMapPosition();let o;if(this.moveOnCurve){var s=this.steerCurve.getLength(),l=Math.min(this.distanceTravelled+a,s);this.carryOverDistance=Math.max(0,this.distanceTravelled+a-s),this.distanceTravelled=l;let e=this.steerCurve.getPointAt(this.distanceTravelled/s),t=this.steerCurve.getTangentAt(this.distanceTravelled/s);l=t.clone().setLength(a);i.moveTrait.velocity.set(l.x,0,l.y);var s=i.rules.rot,{facing:l,delta:s}=FacingUtil.tick(i.direction,FacingUtil.fromMapCoords(t),s);i.direction=l,i.spinVelocity=s;s=this.lastPosition;this.lastPosition=e.clone(),o=e.sub(s)}else{let e=(new Vector2).copy(r).sub(n);n=Math.min(e.length(),a);o=e.clone().setLength(n);let t=o.clone();this.carryOverDistance&&t.add(Coords.vecWorldToGround(i.moveTrait.velocity)),i.moveTrait.velocity.set(t.x,0,t.y),this.distanceTravelled+=n,this.carryOverDistance=Math.max(0,a-e.length())}return{distance:new Vector3_Vector3(o.x,0,o.y),done:!o.length()||!!this.carryOverDistance}}pointTurretToTarget(t,i){if(t.turretTrait){t.attackTrait?.currentTarget?.obj&&(i=t.attackTrait.currentTarget.obj.position.getMapPosition());var r=t.position.getMapPosition();let e=(new Vector2).copy(i).sub(r);e.length()&&(r=FacingUtil.fromMapCoords(e),t.turretTrait.desiredFacing=r)}}applyAcceleration(e,t,i,r){if(this.currentWaypointType===WaypointType.Single)return i/2;if(this.currentWaypointType!==WaypointType.End)return Math.min(t+e.rules.accelerationFactor*i,i);return lerp(1,i,1-(r=this.moveOnCurve&&this.currentWaypointType===WaypointType.End?r<=.5?0:2*(r-.5):r))}}class FootLocomotor{constructor(e){this.game=e,this.currentMoveDirection=new Vector2,this.distanceToWaypoint=new Vector2,this.endPauseFrames=0}onNewWaypoint(e,t){this.currentMoveDirection.copy(t).sub(e.position.getMapPosition());t=FacingUtil.fromMapCoords(this.currentMoveDirection);t!==e.direction&&(e.direction=t),this.endPauseFrames=1}onWaypointUpdate(e,t){this.onNewWaypoint(e,t)}tick(e,t,i){let r=e.moveTrait.baseSpeed;r=Math.floor(r),e.stance===StanceType.Prone&&(r*=e.art.crawls?.5:2),e.isPanicked&&(r*=2);let s=this.game.map.terrain.getPassableSpeed(e.tile,e.rules.speedType,e.isInfantry(),e.onBridge,void 0,!0);s?e.moveTrait.lastTileSpeed=s:s=e.moveTrait.lastTileSpeed||1,r*=s,r=Math.floor(r),this.distanceToWaypoint.copy(t).sub(e.position.getMapPosition());let a=this.distanceToWaypoint.clone().setLength(r);(a.length()||t.equals(i))&&e.moveTrait.velocity.set(a.x,0,a.y);i=Math.min(this.distanceToWaypoint.length(),r),e=!i&&0<this.endPauseFrames--;return this.distanceToWaypoint.setLength(i),{distance:new Vector3_Vector3(this.distanceToWaypoint.x,0,this.distanceToWaypoint.y),done:!this.distanceToWaypoint.length()&&!e}}}!function(e){e[e.None=0]="None",e[e.Start=1]="Start",e[e.Normal=2]="Normal",e[e.End=3]="End",e[e.Single=4]="Single"}(HoverLocomotor_WaypointType=HoverLocomotor_WaypointType||{});class HoverLocomotor{constructor(e){this.hoverRules=e,this.currentSpeed=0,this.distanceTravelled=0,this.carryOverDistance=0,this.currentWaypointType=HoverLocomotor_WaypointType.None,this.nextWaypointDir=new Vector2}selectNextWaypoint(e,t){var i;return this.currentWaypointType=this.currentWaypointType&&this.currentWaypointType!==HoverLocomotor_WaypointType.End?HoverLocomotor_WaypointType.Normal:HoverLocomotor_WaypointType.Start,this.initialPosition=e.position.getMapPosition(),this.currentWaypointType===HoverLocomotor_WaypointType.Start&&(this.currentSpeed=0),t.length<=1?(this.currentWaypointType=this.currentWaypointType===HoverLocomotor_WaypointType.Start?HoverLocomotor_WaypointType.Single:HoverLocomotor_WaypointType.End,(i=t[t.length-1])&&this.nextWaypointDir.set(i.tile.rx-e.tile.rx,i.tile.ry-e.tile.ry)):(i=t[t.length-1],e=t[t.length-2],this.nextWaypointDir.set(e.tile.rx-i.tile.rx,e.tile.ry-i.tile.ry)),t[t.length-1]}onNewWaypoint(e,t,i){let r=(new Vector2).copy(t).sub(this.initialPosition);this.distanceTravelled=0,this.totalDistanceToTravel=r.length();t=this.maxSpeed=e.moveTrait.baseSpeed,e=60*this.hoverRules.acceleration*GameSpeed.BASE_TICKS_PER_SECOND;this.acceleration=t/e;e=60*this.hoverRules.brake*GameSpeed.BASE_TICKS_PER_SECOND;this.deceleration=t/e}tick(e,t){var i=e.position.getMapPosition();let r=t.clone().sub(i);t=r.length(),i=this.maxSpeed;this.currentWaypointType===HoverLocomotor_WaypointType.Single?this.currentSpeed=i/2:this.currentWaypointType===HoverLocomotor_WaypointType.End?(s=this.computeBrakeDistance(this.currentSpeed,this.deceleration),this.totalDistanceToTravel-this.distanceTravelled<=s&&(this.currentSpeed=Math.max(1,this.currentSpeed-this.deceleration))):this.currentSpeed=Math.min(this.currentSpeed+this.acceleration,i);var s=FacingUtil.fromMapCoords(r),i=FacingUtil.fromMapCoords(this.nextWaypointDir);let a=s,n=e.rules.rot;this.currentWaypointType===HoverLocomotor_WaypointType.Normal&&s!==i&&(s=(o=angleDegBetweenVec2(this.nextWaypointDir,FacingUtil.toMapCoords(e.direction)))/n,s=Math.max(this.currentSpeed*s,this.totalDistanceToTravel),this.totalDistanceToTravel-this.distanceTravelled<=s&&(a=i,n=o/((this.totalDistanceToTravel-this.distanceTravelled)/this.currentSpeed)));var o=FacingUtil.tick(e.direction,a,n)["facing"];e.direction=o;let l=this.currentSpeed;this.carryOverDistance&&(l=this.carryOverDistance);o=Math.min(l,t);let h=r.clone().setLength(o),c=h.clone();return this.carryOverDistance&&c.add(Coords.vecWorldToGround(e.moveTrait.velocity)),e.moveTrait.velocity.set(c.x,0,c.y),this.distanceTravelled+=o,this.carryOverDistance=Math.max(0,l-t),{distance:new Vector3_Vector3(h.x,0,h.y),done:!h.length()||!!this.carryOverDistance}}computeBrakeDistance(e,t){var i=e/t;return Math.max(0,e*i-t*i*i/2)}}class TargetUtil{static computeInterceptPoint(e,t,i,r){let s=e.clone().sub(i);var a=r.length(),e=t*t-a*a,t=2*s.dot(r),a=-s.dot(s);if(t*t-4*e*a<0)return new Vector3_Vector3;e=(-t+GameMath.sqrt(t*t-4*e*a))/(2*e);return r.clone().multiplyScalar(e).add(i)}static computeTurnCircle(e,t,i,r){r/=degToRad(Math.abs(i));let s=rotateVec2(t.clone(),90*-Math.sign(i));return{center:isFinite(r)?s.setLength(r).add(e):e.clone(),radius:r}}}var util_geometry_THREE=__webpack_require__(70);function pointEquals(e,t){return e&&t&&e.x===t.x&&e.y===t.y||!e&&!t}function rectIntersect(e,t){return e.x<=t.x+t.width&&t.x<=e.x+e.width&&e.y<=t.y+t.height&&t.y<=e.y+e.height}function rectEquals(e,t){return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height}function circleIntersect(e,t){var i=e.center,r=t.center;return isBetween((i.x-r.x)*(i.x-r.x)+(i.y-r.y)*(i.y-r.y),(e.radius-t.radius)*(e.radius-t.radius),(e.radius+t.radius)*(e.radius+t.radius))}function circleContainsPoint(e,t){var i=e.center;return(i.x-t.x)*(i.x-t.x)+(i.y-t.y)*(i.y-t.y)<=e.radius*e.radius}function rectContainsPoint(e,t){let i=new util_geometry_THREE.Box2(new util_geometry_THREE.Vector2(e.x,e.y),new util_geometry_THREE.Vector2(e.x+e.width,e.y+e.height));return i.containsPoint(new util_geometry_THREE.Vector2(t.x,t.y))}function rectContainsRect(e,t){let i=new util_geometry_THREE.Box2(new util_geometry_THREE.Vector2(e.x,e.y),new util_geometry_THREE.Vector2(e.x+e.width,e.y+e.height));t=new util_geometry_THREE.Box2(new util_geometry_THREE.Vector2(t.x,t.y),new util_geometry_THREE.Vector2(t.x+t.width,t.y+t.height));return i.containsBox(t)}function rectClampPoint(e,t){let i=new util_geometry_THREE.Box2(new util_geometry_THREE.Vector2(e.x,e.y),new util_geometry_THREE.Vector2(e.x+e.width,e.y+e.height));return i.clampPoint(new util_geometry_THREE.Vector2(t.x,t.y),new util_geometry_THREE.Vector2)}function octileDistance(e,t){var i=Math.abs(e.x-t.x),t=Math.abs(e.y-t.y);return i+t+(Math.SQRT2-2)*Math.min(i,t)}class ObjectLiftOffEvent{constructor(e){this.gameObject=e,this.type=EventType.ObjectLiftOff}}class ObjectLandEvent{constructor(e){this.gameObject=e,this.type=EventType.ObjectLand}}const JUMPJET_ACCEL=2;class JumpjetLocomotor{static tickStationary(t,i){if(t.zone===ZoneType.Air){var r=t.tile.onBridgeLandType?i.map.tileOccupation.getBridgeOnTile(t.tile):void 0,s=!t.rules.balloonHover&&(!t.unitOrderTrait.getCurrentTask()?.preventLanding||!t.rules.hoverAttack)&&(i.map.getGroundObjectsOnTile(t.tile).find(e=>e.isBuilding()&&e.dockTrait?.isDocked(t))||i.map.getTileZone(t.tile)!==ZoneType.Water&&0<i.map.terrain.getPassableSpeed(t.tile,SpeedType.Foot,!0,!!t.tile.onBridgeLandType)&&0===i.map.terrain.findObstacles({tile:t.tile,onBridge:r},t).length);let e;e=s?(a=t.tile.z+(r?.tileElevation??0),Coords.tileHeightToWorld(a)):(n=t.tile.z+i.map.getGroundObjectsOnTile(t.tile).filter(e=>!(e.isInfantry()&&e.stance===StanceType.Paradrop)).reduce((e,t)=>Math.max(e,t.tileElevation+t.art.height),0),Coords.tileHeightToWorld(n)+t.rules.jumpjetHeight);var a,n,o=t.position.worldPosition.y;e!==o?(a=t.rules.jumpjetClimb,n=Math.abs(e-o),a=Math.sign(e-o)*Math.min(a,n),n=t.tileElevation,t.position.moveByLeptons3(new Vector3_Vector3(0,a,0)),t.moveTrait.handleElevationChange(n,i)):s&&(t.zone=ZoneType.Ground,t.onBridge=!!r,i.events.dispatch(new ObjectLandEvent(t)),(r=i.map.tileOccupation.getGroundObjectsOnTile(t.tile).find(e=>e.isOverlay()&&e.rules.crate))&&i.crateGeneratorTrait.pickupCrate(t,r,i))}}static tickCrash(e,t,i){var r=2*e.rules.jumpjetCrash;return e.direction=(e.direction-6+360)%360,new Vector3_Vector3(0,-r,0)}constructor(e){this.game=e,this.allowOutOfBounds=!0,this.currentMoveDir=new Vector2,this.currentHorizSpeed=0}onNewWaypoint(e,t,i){this.currentMoveDir=FacingUtil.toMapCoords(e.direction),this.cancelDestLeptons=void 0}tick(t,e,i,r){if(t.zone!==ZoneType.Air&&(t.onBridge=!1,t.zone=ZoneType.Air,this.game.events.dispatch(new ObjectLiftOffEvent(t))),r){if(!this.cancelDestLeptons){let e=t.tile;this.game.map.isWithinBounds(e)||(e=this.game.map.clampWithinBounds(e)),this.cancelDestLeptons=this.computeCancelDest(e,i)}i=this.cancelDestLeptons}var s=t.position.getMapPosition();let a=i.clone().sub(s),n=this.findTilesToCheckForBlockers(t.tile,s,this.currentMoveDir,a.length());var o=n.map(e=>e.z+this.game.map.getGroundObjectsOnTile(e).filter(e=>!(e.isDestroyed||e.isInfantry()&&e.stance===StanceType.Paradrop)).reduce((e,t)=>Math.max(e,t.tileElevation+t.art.height),0)).reduce((e,t)=>Math.max(e,t),0);let l=0;(void 0===this.lastClearZ||2<o-this.lastClearZ)&&(l=4);var h=Coords.tileHeightToWorld(o),c=Coords.tileHeightToWorld(o+l),u=t.position.worldPosition.y,d=FacingUtil.fromMapCoords(a),p=a.length()<t.rules.jumpjetSpeed;let g=0;h<=u&&!p&&({facing:v,delta:r}=FacingUtil.tick(t.direction,d,t.rules.jumpjetTurnRate),g=r,t.direction=v,this.currentMoveDir.copy(FacingUtil.toMapCoords(t.direction))),t.isVehicle()&&(t.spinVelocity=g);let m,y=!1,T=0,f=0;var v=t.rules.jumpjetClimb;u<c?(T=Math.min(v,c-u),m=!1,this.currentHorizSpeed=0):(this.lastClearZ=o,o=h+t.rules.jumpjetHeight,m=!0,o!==u&&(h=Math.abs(o-u),T=Math.sign(o-u)*Math.min(v,h),m=h<=v),v=this.currentHorizSpeed,this.currentHorizSpeed=Math.min(this.currentHorizSpeed+JUMPJET_ACCEL,t.rules.jumpjetSpeed),y=d===t.direction?(f=Math.min(v,a.length()),v>=a.length()):((s=v||g?TargetUtil.computeTurnCircle(s,this.currentMoveDir,Math.sign(g)*t.rules.jumpjetTurnRate,v):void 0)&&circleContainsPoint(s,i)?(f=0,this.currentHorizSpeed=0):f=v,!1));let b;b=p?(y=!0,a):this.currentMoveDir.clone().setLength(f);let w=new Vector3_Vector3(b.x,T,b.y);p=w.clone();return t.moveTrait.velocity.copy(p),{distance:w,done:y&&m}}findTilesToCheckForBlockers(e,t,i,r){r=i.clone().setLength(Math.min(r,Coords.LEPTONS_PER_TILE)).add(t).multiplyScalar(1/Coords.LEPTONS_PER_TILE).floor(),t=this.game.map.tiles.getByMapCoords(r.x,r.y);if(!t||t===e)return[e];r=Math.sign(t.rx-e.rx),t=Math.sign(t.ry-e.ry);let s=[e],a;return r&&(a=this.game.map.tiles.getByMapCoords(e.rx+r,e.ry),a&&s.push(a)),t&&(a=this.game.map.tiles.getByMapCoords(e.rx,e.ry+t),a&&s.push(a)),r&&t&&(a=this.game.map.tiles.getByMapCoords(e.rx+r,e.ry+t),a&&s.push(a)),s}computeCancelDest(e,t){var i=t.clone().multiplyScalar(1/Coords.LEPTONS_PER_TILE).floor().multiplyScalar(Coords.LEPTONS_PER_TILE),i=t.clone().sub(i);return new Vector2(e.rx,e.ry).multiplyScalar(Coords.LEPTONS_PER_TILE).add(i)}}var FlightPhase,NotifyTick_NotifyTick,DockingStatus,ManeuverType,NotifyTeleport,NotifyDestroy,DeathType,NotifyTileChange,NotifyTileChange_NotifyTileChange,NotifyElevationChange,MoveState,MoveResult,CollisionState,NotifyOwnerChange,NotifySpawn,NotifyUnspawn,NotifyAttack,VeteranLevel,NotifyCrash,ParadropState,OverlayBridgeType,NotifyAttack_NotifyAttack,CollisionType,TileDirection,SpecialWarheadType,State,NotifySuperWeaponDeactivate,NotifyDamage,TiberiumType,CubicBezierCurve3_THREE=__webpack_require__(70);class CubicBezierCurve3 extends CubicBezierCurve3_THREE.CubicBezierCurve3{constructor(e,t,i,r){super(e||new Vector3_Vector3,t||new Vector3_Vector3,i||new Vector3_Vector3,r||new Vector3_Vector3)}getPoint(e,t){return super.getPoint(e,t||new Vector3_Vector3)}}!function(e){e[e.Boost=0]="Boost",e[e.Midcourse=1]="Midcourse",e[e.Terminal=2]="Terminal"}(FlightPhase=FlightPhase||{});class MissileLocomotor{constructor(e,t){this.game=e,this.missileRules=t,this.flightPhase=FlightPhase.Boost}selectNextWaypoint(e,t){var i=t[t.length-1],t=this.game.map.tileOccupation.getBridgeOnTile(i.tile),t=i.tile.z+(t?.tileElevation??0);return this.targetPosition=Coords.tile3dToWorld(i.tile.rx+.5,i.tile.ry+.5,t),this.cruiseAltitude=Coords.tileHeightToWorld(t)+this.missileRules.altitude,i}onNewWaypoint(e,t,i){}tick(i,e,t){let r=i.position.worldPosition.clone(),s=this.targetPosition.clone().sub(r);i.zone!==ZoneType.Air&&(i.onBridge=!1,i.zone=ZoneType.Air,this.game.events.dispatch(new ObjectLiftOffEvent(i)));let a;var n;a=this.currentVelocity?(n=i.rules.speed,Math.min(this.currentVelocity.length()+this.missileRules.acceleration,n)):(p=this.missileRules.acceleration,this.missileRules.lazyCurve?this.currentVelocity=new Vector3_Vector3(s.x,0,s.z):this.currentVelocity=Coords.vecGroundToWorld(FacingUtil.toMapCoords(i.direction)),rotateVec3Towards(this.currentVelocity,new Vector3_Vector3(this.currentVelocity.x,1e8,this.currentVelocity.z),i.pitch),p),this.currentVelocity.setLength(a);let o=!1;switch(this.flightPhase){case FlightPhase.Boost:if(!(i.position.worldPosition.y>=this.cruiseAltitude)){o=!1;break}this.flightPhase=FlightPhase.Midcourse;case FlightPhase.Midcourse:var l,h=new Vector2(s.x,s.z).length();if(!this.missileRules.lazyCurve){rotateVec3Towards(this.currentVelocity,new Vector3_Vector3(this.currentVelocity.x,0,this.currentVelocity.z),i.rules.rot),this.currentVelocity.y<1&&(l=this.currentVelocity.length(),this.currentVelocity.y=0,this.currentVelocity.setLength(l)),rotateVec3Towards(this.currentVelocity,new Vector3_Vector3(s.x,this.currentVelocity.y,s.z),i.rules.rot),i.direction=FacingUtil.fromMapCoords(Coords.vecWorldToGround(this.currentVelocity)),i.pitch=Math.sign(this.currentVelocity.y)*angleDegBetweenVec3(this.currentVelocity,new Vector3_Vector3(this.currentVelocity.x,0,this.currentVelocity.z)),h/(r.y-this.targetPosition.y)<1&&(this.flightPhase=FlightPhase.Terminal);break}this.flightPhase=FlightPhase.Terminal;var c=r.clone().add(this.currentVelocity.clone().setLength(h/3/GameMath.cos(degToRad(i.pitch)))),u=this.targetPosition.clone().lerp(r,.15).setY(c.y);this.descentCurve=new CubicBezierCurve3(r,c,u,this.targetPosition);case FlightPhase.Terminal:c=this.missileRules.bodyLength;if(this.missileRules.lazyCurve){var d=this.descentCurve.getLength();this.descentTravelled??(this.descentTravelled=0),this.descentTravelled+=Math.min(a,d-c-this.descentTravelled);u=this.descentTravelled/d;let e=this.descentCurve.getPointAt(u),t=this.descentCurve.getTangentAt(u);this.currentVelocity.copy(e.sub(r));u=t.clone().setY(0);i.pitch=Math.sign(t.y-u.y)*angleDegBetweenVec3(u,t),o=1<=(this.descentTravelled+c)/d}else{rotateVec3Towards(this.currentVelocity,s,i.rules.rot),i.direction=FacingUtil.fromMapCoords(Coords.vecWorldToGround(this.currentVelocity)),i.pitch=Math.sign(this.currentVelocity.y)*angleDegBetweenVec3(this.currentVelocity,new Vector3_Vector3(this.currentVelocity.x,0,this.currentVelocity.z));d=s.length()-c;(d<a||d<1)&&(this.currentVelocity.copy(s.clone().addScalar(-c)),o=!0)}break;default:throw new Error(`Unhandled flight phase "${this.flightPhase}"`)}var p=r.clone().add(this.currentVelocity);return this.game.map.isWithinHardBounds(p)?(i.moveTrait.velocity.copy(this.currentVelocity),{distance:this.currentVelocity,done:o}):(this.game.destroyObject(i),{done:!0,distance:new Vector3_Vector3})}}class WaitMinutesTask extends WaitTicksTask{constructor(e){super(Math.floor(GameSpeed.BASE_TICKS_PER_SECOND*e*60))}}class CallbackTask extends Task{constructor(e){super(),this.cb=e}onTick(e){return this.cb(e),!0}}(NotifyTick_NotifyTick=NotifyTick_NotifyTick||{}).onTick=Symbol(),function(e){e[e.Idle=0]="Idle",e[e.MoveToQueueingTile=1]="MoveToQueueingTile",e[e.WaitForTurn=2]="WaitForTurn",e[e.MoveToDock=3]="MoveToDock",e[e.Docking=4]="Docking",e[e.Docked=5]="Docked"}(DockingStatus=DockingStatus||{});class MoveToDockTask extends Task{constructor(e,t){super(),this.game=e,this.target=t,this.useChildTargetLines=!0,this.preventOpportunityFire=!1,this.dockingStatus=DockingStatus.Idle}onStart(e){if(!this.target.dockTrait)throw new Error(`Target object "${this.target.name}" is not a valid dock`);var t;this.target.dockTrait.hasReservedDockForUnit(e)?this.dockingStatus=DockingStatus.MoveToDock:void 0!==(t=this.target.dockTrait.getFirstAvailableDockNumber())?(this.target.dockTrait.reserveDockAt(e,t),this.dockingStatus=DockingStatus.MoveToDock):this.target.helipadTrait?this.cancel():this.dockingStatus=DockingStatus.MoveToQueueingTile}onEnd(e){this.dockingStatus!==DockingStatus.Docked&&this.target.isSpawned&&(this.target.dockTrait.undockUnit(e),this.target.dockTrait.unreserveDockForUnit(e)),this.dockingStatus=DockingStatus.Idle}onTick(e){if(this.isCancelling())return!0;if(!this.isValidTarget(this.target,e))return!0;if(this.dockingStatus===DockingStatus.MoveToQueueingTile){var t=this.findReachableQueueingTile(e);if(!t)return!0;if(e.tile!==t)return this.children.push(new MoveTask(this.game,t,!1,{closeEnoughTiles:5}),new CallbackTask(()=>{e.moveTrait.lastMoveResult===MoveResult.Fail?this.cancel():e.moveTrait.lastMoveResult===MoveResult.CloseEnough&&(this.game.map.tileOccupation.isTileOccupiedBy(e.tile,this.target)||(this.dockingStatus=DockingStatus.WaitForTurn))})),!1;this.dockingStatus=DockingStatus.WaitForTurn}if(this.dockingStatus===DockingStatus.WaitForTurn){var i=this.target.dockTrait.getFirstAvailableDockNumber();if(void 0===i)return this.children.push(new WaitMinutesTask(1/60)),!1;this.target.dockTrait.reserveDockAt(e,i),this.dockingStatus=DockingStatus.MoveToDock}if(this.dockingStatus===DockingStatus.MoveToDock){var r=this.target.dockTrait.getReservedDockForUnit(e),i=this.target.dockTrait.getDockTile(r),r=Coords.vecWorldToGround(this.target.dockTrait.getDockOffset(r)).add(this.target.position.getMapPosition()).sub(new Vector2(i.rx,i.ry).multiplyScalar(Coords.LEPTONS_PER_TILE));if(e.tile!==i)return this.children.push(new MoveTask(this.game,i,!1,{targetOffset:e.isAircraft()?r:void 0,closeEnoughTiles:0,strictCloseEnough:!0}),new CallbackTask(()=>{e.moveTrait.lastMoveResult===MoveResult.Fail&&this.cancel()})),this.game.afterTick(()=>e.unitOrderTrait[NotifyTick_NotifyTick.onTick](e,this.game)),!1;this.dockingStatus=DockingStatus.Docking}if(this.dockingStatus!==DockingStatus.Docking)return!1;r=this.target.dockTrait.getReservedDockForUnit(e);return this.target.dockTrait.unreserveDockForUnit(e),this.target.dockTrait.dockUnitAt(e,r),e.isAircraft()&&e.airportBoundTrait&&this.target.helipadTrait&&(e.airportBoundTrait.preferredAirport=this.target),this.dockingStatus=DockingStatus.Docked,!0}isValidTarget(e,t){return e.isSpawned&&this.game.areFriendly(e,t)}findReachableQueueingTile(t){var e=this.target.getFoundation(),e=new Vector2(this.target.tile.rx+e.width,this.target.tile.ry+e.height),e=this.game.map.tiles.getByMapCoords(e.x,e.y);return e&&this.isValidQueueingTile(e,t)?e:new RadialTileFinder(this.game.map.tiles,this.game.map.mapBounds,this.target.tile,this.target.getFoundation(),1,1,e=>this.isValidQueueingTile(e,t)).getNextTile()}isValidQueueingTile(e,t){var i=t.rules.movementZone===MovementZone.Fly,r=t.rules.speedType,s=t.isInfantry();let a=!i&&this.game.map.terrain.getPassableSpeed(t.tile,r,s,t.onBridge)?this.game.map.terrain.getIslandIdMap(r,s):void 0;return(i||a?.get(e,!1)===a?.get(t.tile,t.onBridge)&&Math.abs(e.z-this.target.tile.z)<2&&!e.onBridgeLandType&&!this.game.map.terrain.findObstacles({tile:e,onBridge:void 0},t).length)&&!this.game.map.tileOccupation.isTileOccupiedBy(e,this.target)}}const WINGED_ACCEL=2,WINGED_DECEL=2,WINGED_CLIMB=30,STATIONARY_FACING=270,STATIONARY_THRESH=5;!function(e){e[e.None=0]="None",e[e.CircleStrafe=1]="CircleStrafe",e[e.HoverStrafe=2]="HoverStrafe"}(ManeuverType=ManeuverType||{});class WingedLocomotor{static tickStationary(s,a){if(s.zone===ZoneType.Air){var n=s.tile.onBridgeLandType?a.map.tileOccupation.getBridgeOnTile(s.tile):void 0;let e=s.rules.landable&&!s.unitOrderTrait.getCurrentTask()?.preventLanding,i=s.spawnLinkTrait?.getParent();e&&i?e=!((!i.isUnit()||!i.onBridge)&&n||i.tile!==s.tile):e&&!s.airportBoundTrait&&(e=a.map.getTileZone(s.tile)!==ZoneType.Water&&0<a.map.terrain.getPassableSpeed(s.tile,SpeedType.Foot,!0,!!s.tile.onBridgeLandType)&&0===a.map.terrain.findObstacles({tile:s.tile,onBridge:n},s).length);let r;if(e){let e=s.airportBoundTrait?.preferredAirport?.dockTrait;var o=e?.isDocked(s)||e?.hasReservedDockForUnit(s);if(!s.airportBoundTrait||o){o=o?0:STATIONARY_FACING;if(s.direction!==o)return void(s.direction=FacingUtil.tick(s.direction,o,s.rules.rot).facing)}if(s.airportBoundTrait){let e=s.airportBoundTrait.preferredAirport;if(!e?.dockTrait?.isDocked(s))return e?.dockTrait?.getAvailableDockCount()||(e=s.airportBoundTrait.findAvailableAirport(s),s.airportBoundTrait.preferredAirport=e,e&&(h=e.dockTrait.getFirstAvailableDockNumber(),e.dockTrait.reserveDockAt(s,h))),void(e?(s.unitOrderTrait.addTask(new MoveToDockTask(a,e)),s.unitOrderTrait[NotifyTick_NotifyTick.onTick](s,a)):s.crashableTrait.crash(void 0))}let t;t=i?i.tile.z+i.tileElevation:s.tile.z+(n?.tileElevation??0),r=Coords.tileHeightToWorld(t)}else{var t=s.tile.z+(n?.tileElevation??0),l=s.rules.flightLevel??a.rules.general.flightLevel;r=Coords.tileHeightToWorld(t)+l}var h=s.position.worldPosition.y;r!==h?(t=WINGED_CLIMB,l=Math.abs(r-h),t=Math.sign(r-h)*Math.min(t,l),l=s.tileElevation,s.position.moveByLeptons3(new Vector3_Vector3(0,t,0)),s.moveTrait.handleElevationChange(l,a)):e&&(s.zone=ZoneType.Ground,i?i.airSpawnTrait.storeAircraft(s,a):s.onBridge=!!n,a.events.dispatch(new ObjectLandEvent(s)),(n=a.map.tileOccupation.getGroundObjectsOnTile(s.tile).find(e=>e.isOverlay()&&e.rules.crate))&&a.crateGeneratorTrait.pickupCrate(s,n,a))}}static tickCrash(e,t,i){var r=WINGED_CLIMB;i.rollDelta??(i.rollDelta=t.generateRandomInt(-15,15)),i.pitchDelta??(i.pitchDelta=t.generateRandomInt(0,15)),e.roll+=i.rollDelta,e.pitch+=i.pitchDelta;e=Coords.vecWorldToGround(e.moveTrait.velocity);return new Vector3_Vector3(e.x,-r,e.y)}constructor(e){this.game=e,this.allowOutOfBounds=!0,this.lastDestLeptons=new Vector2,this.currentMoveDir=new Vector2,this.currentHorizSpeed=0,this.maneuverType=ManeuverType.None,this.deceleratingToTurn=!1}onNewWaypoint(e,t,i){this.currentHorizSpeed=Coords.vecWorldToGround(e.moveTrait.velocity).length(),this.cancelDestLeptons=void 0}tick(t,e,i,r){if(r){if(!this.cancelDestLeptons){let e=t.tile;this.game.map.isWithinBounds(e)||(e=this.game.map.clampWithinBounds(e)),this.cancelDestLeptons=this.computeCancelDest(e,i)}i=this.cancelDestLeptons}var s=t.position.getMapPosition();let a=i.clone().sub(s);var n=a.length();this.lastDestLeptons.equals(i)||(this.lastDestLeptons.copy(i),r?this.maneuverType=ManeuverType.HoverStrafe:t.zone===ZoneType.Air&&this.currentHorizSpeed<STATIONARY_THRESH?this.maneuverType=n>Coords.LEPTONS_PER_TILE?ManeuverType.CircleStrafe:ManeuverType.HoverStrafe:this.maneuverType=ManeuverType.None,this.deceleratingToTurn=!1),t.zone!==ZoneType.Air&&(t.onBridge=!1,t.zone=ZoneType.Air,this.game.events.dispatch(new ObjectLiftOffEvent(t)));var o=t.tile.onBridgeLandType?this.game.map.tileOccupation.getBridgeOnTile(t.tile):void 0,l=t.tile.z+(o?.tileElevation??0),h=t.rules.flightLevel??this.game.rules.general.flightLevel,c=Coords.tileHeightToWorld(l)+h,r=t.position.worldPosition.y,u=FacingUtil.fromMapCoords(a);t.direction===u&&this.maneuverType===ManeuverType.None&&n<=Coords.LEPTONS_PER_TILE?this.maneuverType=ManeuverType.HoverStrafe:t.direction===u&&this.maneuverType===ManeuverType.CircleStrafe&&(this.maneuverType=ManeuverType.None);let d;switch(this.maneuverType){case ManeuverType.HoverStrafe:if(t.attackTrait?.currentTarget){let e=Coords.vecWorldToGround(t.attackTrait.currentTarget.getWorldCoords());d=FacingUtil.fromMapCoords(e.sub(s))}else d=t.airportBoundTrait?.preferredAirport?.dockTrait?.hasReservedDockForUnit(t)?0:STATIONARY_FACING;break;case ManeuverType.CircleStrafe:case ManeuverType.None:d=u;break;default:throw new Error('Unknown maneuver type "'+this.maneuverType)}var{facing:p,delta:g}=FacingUtil.tick(t.direction,d,t.rules.rot);t.direction=p,t.roll=Math.sign(g)*t.rules.pitchAngle;let m;switch(this.maneuverType){case ManeuverType.HoverStrafe:m=u;break;case ManeuverType.CircleStrafe:m=(p-90*Math.sign(g)+360)%360;break;case ManeuverType.None:m=p;break;default:throw new Error('Unknown maneuver type "'+this.maneuverType)}void 0===this.thrustFacing&&(this.thrustFacing=m);var o=this.currentHorizSpeed>STATIONARY_THRESH?t.rules.rot:Number.POSITIVE_INFINITY,{facing:l,delta:h}=FacingUtil.tick(this.thrustFacing,m,o);this.thrustFacing=l,this.currentMoveDir.copy(FacingUtil.toMapCoords(this.thrustFacing));let y=!1,T=0,f=0;o=WINGED_CLIMB;let v=!0;c!==r&&(l=Math.abs(c-r),T=Math.sign(c-r)*Math.min(o,l),v=l<=o);let b=t.rules.speed;n<=Coords.LEPTONS_PER_TILE&&this.maneuverType!==ManeuverType.CircleStrafe&&(b=lerp(1,b/2,GameMath.sqrt(n/Coords.LEPTONS_PER_TILE))),this.deceleratingToTurn?this.currentHorizSpeed=Math.max(0,this.currentHorizSpeed-WINGED_DECEL):this.currentHorizSpeed=Math.min(this.currentHorizSpeed+WINGED_ACCEL,b);o=this.currentHorizSpeed;this.deceleratingToTurn=!1,y=h?(h=o||h?TargetUtil.computeTurnCircle(s,this.currentMoveDir,Math.sign(h)*t.rules.rot,o):void 0,0!==o&&!circleContainsPoint(h,i)||(this.maneuverType===ManeuverType.HoverStrafe||n>Coords.LEPTONS_PER_TILE?this.deceleratingToTurn=!0:this.maneuverType===ManeuverType.None&&(this.maneuverType=ManeuverType.HoverStrafe)),f=o,!1):(f=Math.min(o,n),n<=o);let w;w=n<1?(y=!0,a):y?a:this.currentMoveDir.clone().setLength(f);let S=new Vector3_Vector3(w.x,T,w.y);n=S.clone();return t.moveTrait.velocity.copy(n),{distance:S,done:y&&v}}computeCancelDest(e,t){var i=t.clone().multiplyScalar(1/Coords.LEPTONS_PER_TILE).floor().multiplyScalar(Coords.LEPTONS_PER_TILE),i=t.clone().sub(i);return new Vector2(e.rx,e.ry).multiplyScalar(Coords.LEPTONS_PER_TILE).add(i)}}class LocomotorFactory{constructor(e){this.game=e}create(e){var t=e.rules.locomotor;switch(t){case LocomotorType.Infantry:return new FootLocomotor(this.game);case LocomotorType.Jumpjet:return new JumpjetLocomotor(this.game);case LocomotorType.Vehicle:case LocomotorType.Ship:return new DriveLocomotor(this.game);case LocomotorType.Chrono:return e.isVehicle()&&e.harvesterTrait&&e.rules.teleporter?new DriveLocomotor(this.game):new ChronoLocomotor(this.game);case LocomotorType.Aircraft:return new WingedLocomotor(this.game);case LocomotorType.Missile:return new MissileLocomotor(this.game,this.game.rules.general.getMissileRules(e.name));case LocomotorType.Hover:return new HoverLocomotor(this.game.rules.general.hover);default:throw new Error("Unhandled locomotor type "+t)}}}class RandomTileFinder{constructor(e,t,i,r,s,a,n=!1,o=!0){this.tiles=e,this.mapBounds=t,this.startTile=i,this.maxDistance=r,this.rng=s,this.predicate=a,this.includeStartTile=n,this.checkBounds=o,this.pool=[],this.pool=new Array(GameMath.pow(2*this.maxDistance+1,2)).fill(0).map((e,t)=>t),this.generator=this.generate()}getNextTile(){return this.generator.next().value}*generate(){for(var e=(e,t)=>{t=this.tiles.getByMapCoords(e,t);if(this.includeStartTile||t!==this.startTile)return t&&(!this.checkBounds||this.mapBounds.isWithinBounds(t))&&this.predicate(t)?t:void 0},t=2*this.maxDistance+1;this.pool.length;){var i=1<this.pool.length?this.rng.generateRandomInt(0,this.pool.length):0,r=this.pool.splice(i,1)[0],i=r%t,r=Math.floor(r/t),r=e(this.startTile.rx-this.maxDistance+i,this.startTile.ry-this.maxDistance+r);r&&(yield r)}}}class ObjectTeleportEvent{constructor(e,t,i){this.target=e,this.isChronoshift=t,this.prevTile=i,this.type=EventType.ObjectTeleport}}(NotifyTeleport=NotifyTeleport||{}).onBeforeTeleport=Symbol();class ScatterPositionHelper{constructor(e){this.game=e,this.movePositionHelper=new MovePositionHelper(e.map)}findPositions(e,t){let i=new Set,r=new Map;for(var s of e){var a=this.findFreeMovePosition(s,i,t);a&&(r.set(s,a),i.add(a.tile))}return r}findFreeMovePosition(i,e,{ignoredBlockers:t,excludedTiles:r,noSlopes:s}={}){let a=this.game.map,n=i.onBridge?a.tileOccupation.getBridgeOnTile(i.tile):void 0,o=new RandomTileFinder(a.tiles,a.mapBounds,i.tile,1,this.game,e=>{if(r?.includes(e))return!1;var t=a.tileOccupation.getBridgeOnTile(e);return(t&&this.movePositionHelper.isEligibleTile(e,t,n,i.tile)||this.movePositionHelper.isEligibleTile(e,void 0,n,i.tile))&&(!s||0===e.rampType)}),l,h;for(;;){var c=o.getNextTile();if(!c)break;if(l=c,h=a.tileOccupation.getBridgeOnTile(c),h&&!this.movePositionHelper.isEligibleTile(c,h,n,i.tile)&&(h=void 0),!e.has(c)){let e=a.terrain.findObstacles({tile:c,onBridge:h},i);if(t&&t.length&&(e=e.filter(e=>!t.includes(e.obj))),!e.length)break}}if(l)return{tile:l,onBridge:h}}}class ScatterTask extends Task{constructor(e,t,i){super(),this.game=e,this.target=t,this.options=i}onStart(i){if(!i.moveTrait.isDisabled()&&i.rules.movementZone!==MovementZone.Fly){let e,t;if(this.target)({tile:e,toBridge:t}=this.target);else{i=new ScatterPositionHelper(this.game).findPositions([i],this.options).get(i);if(!i)return;e=i.tile,t=!!i.onBridge}this.children.push(new MoveTask(this.game,e,t,{closeEnoughTiles:0,ignoredBlockers:this.options?.ignoredBlockers}))}}onTick(e){return!0}}const SPEED_MULT=1.5,PLANNING_BAILOUT_TICKS=200,MoveTask_RETRY_TICKS=40,MAX_UNREACH_TILES_BAIL=5;class MoveTask extends Task{constructor(e,t,i,r){super(),this.game=e,this.targetTile=t,this.toBridge=i,this.options=r,this.preventOpportunityFire=!1,this.logger=AppLogger.get("move"),this.destinationLeptons=new Vector2,this.currentWaypointLeptons=new Vector2,this.needsPathUpdate=!1,this.allObstaclesAreBlockers=!1,this.blockedPathNodes=[],this.unreachableTargets=[],this.pushTried=!1,this.cancelProcessed=!1,this.cancelRepositionPending=!1,this.targetLinesConfig={pathNodes:[]}}duplicate(){return new MoveTask(this.game,this.targetTile,this.toBridge,this.options)}setForceMove(e){e?(this.options??(this.options={}),this.options.forceMove=!0):this.options?.forceMove&&(this.options.forceMove=void 0)}onStart(e){if(e.moveTrait.currentWaypoint)throw new Error("Nested move tasks are not supported");void 0===e.moveTrait.locomotor&&(e.moveTrait.locomotor=new LocomotorFactory(this.game).create(e)),e.moveTrait.lastTargetOffset?this.targetOffset=e.moveTrait.lastTargetOffset:this.targetOffset=this.computeTargetOffset(e),e.moveTrait.lastVelocity&&(e.moveTrait.velocity=e.moveTrait.lastVelocity),this.path||(this.groundPathPlan?(this.groundPathPlan.path[this.groundPathPlan.path.length-1].tile===e.tile?this.path=this.applyGroundPathPlan(this.groundPathPlan):this.computePath(e,e.moveTrait.locomotor),this.groundPathPlan=void 0):this.computePath(e,e.moveTrait.locomotor),this.targetLinesConfig.isRecalc=!1),this.updateDestination(this.path,this.targetOffset),e.moveTrait.moveState=MoveState.ReachedNextWaypoint,e.moveTrait.lastMoveResult=void 0,e.moveTrait.lastTargetOffset=void 0,e.moveTrait.lastVelocity=void 0}computeTargetOffset(e){return this.options?.targetOffset??(e.isInfantry()?e.position.getTileOffset():e.position.computeSubCellOffset(0))}computePath(e,t,i=!1){let r;if(this.options?.allowOutOfBoundsTarget||this.game.map.mapBounds.isWithinBounds(this.targetTile))if(e.rules.movementZone===MovementZone.Fly)r=this.computeAirPath(e);else if(t.ignoresTerrain)r=this.computeDirectJumpPath(e);else{t=this.computeGroundPath(e);if(i&&!t.path.length)return!1;r=this.applyGroundPathPlan(t)}else r=[];return e.rules.movementZone===MovementZone.Fly?(this.targetLinesConfig.pathNodes=r.map(({tile:e,onBridge:t})=>({tile:e,onBridge:t})),r.length&&(this.targetLinesConfig.pathNodes[0].onBridge=this.toBridge?this.game.map.tileOccupation.getBridgeOnTile(this.targetTile):void 0)):this.targetLinesConfig.pathNodes=r,this.path=r,!0}computeAirPath(e){return[{tile:this.targetTile,onBridge:void 0},{tile:e.tile,onBridge:void 0}]}computeDirectJumpPath(t){let i=this.game.map;var e=t.onBridge?i.tileOccupation.getBridgeOnTile(t.tile):void 0;let r=this.targetTile,s=this.toBridge?i.tileOccupation.getBridgeOnTile(this.targetTile):void 0,a=this.options?.ignoredBlockers;var n=new RadialTileFinder(i.tiles,i.mapBounds,r,{width:1,height:1},0,5,e=>0<i.terrain.getPassableSpeed(e,t.rules.speedType,t.isInfantry(),!!e.onBridgeLandType,a)&&!i.terrain.findObstacles({tile:e,onBridge:!!e.onBridgeLandType},t).find(e=>!a?.includes(e.obj))).getNextTile();return n?(n!==r&&(r=n,s=i.tileOccupation.getBridgeOnTile(r)),[{tile:r,onBridge:s},{tile:t.tile,onBridge:e}]):[]}computeGroundPath(t){let e=t.tile,i=t.onBridge?this.game.map.tileOccupation.getBridgeOnTile(e):void 0;t.moveTrait.moveState===MoveState.Moving&&t.moveTrait.currentWaypoint&&(e=t.moveTrait.currentWaypoint.tile,i=t.moveTrait.currentWaypoint.onBridge);let r={path:[],ignoredBlockers:[],blockedPathNodes:[]};const s=this.game.map.getObjectsOnTile(e).find(e=>e.isBuilding());if(s&&!this.game.map.terrain.getPassableSpeed(e,t.rules.speedType,t.isInfantry(),!1)){var a=this.options?.ignoredBlockers?.includes(s);if(a||r.ignoredBlockers.push(s),!a&&s.dockTrait){let t=new Set(s.dockTrait?.getAllDockTiles()),e=this.game.map.tileOccupation.calculateTilesForGameObject(s.tile,s);e.filter(e=>!t.has(e)).forEach(e=>r.blockedPathNodes.push({node:{tile:e,onBridge:void 0},obj:s}))}}var n=this.game.map.getGroundObjectsOnTile(this.targetTile).find(e=>(e.isInfantry()||e.isVehicle())&&e.disguiseTrait?.hasTerrainDisguise()&&!(this.game.alliances.haveSharedIntel(t.owner,e.owner)||e.owner.sharedDetectDisguiseTrait?.has(t)));n&&(a=this.toBridge?this.game.map.tileOccupation.getBridgeOnTile(this.targetTile):void 0,r.blockedPathNodes.push({node:{tile:this.targetTile,onBridge:a},obj:n}));let o=[...new Set([...this.options?.ignoredBlockers??[],...r.ignoredBlockers])],l=[...this.blockedPathNodes,...r.blockedPathNodes];n=this.game.map.terrain.computePath(t.rules.speedType,t.isInfantry(),e,!!i,this.targetTile,this.toBridge,{maxExpandedNodes:this.allObstaclesAreBlockers?Math.min(300,this.options?.maxExpandedPathNodes??Number.POSITIVE_INFINITY):this.options?.maxExpandedPathNodes,bestEffort:!this.options?.strictCloseEnough,ignoredBlockers:[...new Set([...o,...this.options?.pathFinderIgnoredBlockers??[]])],excludeTiles:this.allObstaclesAreBlockers||l.length?e=>this.nodeIsBlockedForPathfinding(e,t,o,l):void 0});return r.path=n,r}nodeIsBlockedForPathfinding(t,e,i,r){return this.allObstaclesAreBlockers?!!this.game.map.terrain.findObstacles(t,e).find(e=>!i?.includes(e.obj)):!!r.find(({node:e})=>e.tile===t.tile&&e.onBridge===t.onBridge)}applyGroundPathPlan(e){var t;return this.blockedPathNodes=this.blockedPathNodes.filter(e=>e.obj.isSpawned&&e.node.tile===e.obj.tile),e.ignoredBlockers.length&&(this.options??(this.options={}),(t=this.options).ignoredBlockers??(t.ignoredBlockers=[]),this.options.ignoredBlockers.push(...e.ignoredBlockers)),this.blockedPathNodes.push(...e.blockedPathNodes),e.path}updateDestination(e,t){e=e.length?e[0].tile:this.targetTile;this.destinationLeptons.set(e.rx*Coords.LEPTONS_PER_TILE,e.ry*Coords.LEPTONS_PER_TILE).add(t)}canStopAtTile(t,i,r){if(t.zone===ZoneType.Air){if((!t.isAircraft()||!t.airportBoundTrait)&&!t.rules.spawned&&(!this.options?.forceMove||!t.rules.balloonHover||t.rules.hoverAttack)&&(!this.game.map.terrain.getPassableSpeed(i,SpeedType.Amphibious,!1,r)||this.game.map.getObjectsOnTile(i).filter(e=>e.isBuilding()&&!e.isDestroyed&&!e.dockTrait?.hasReservedDockForUnit(t)&&!t.rules.dock.includes(e.name)||e.isUnit()&&e.tile===i&&e.moveTrait.moveState!==MoveState.Moving&&e!==t).length))return!1}else if(t.isInfantry()){let e=this.game.map.getGroundObjectsOnTile(i).filter(e=>e.isInfantry()&&e.tile===i&&e.onBridge===r&&e.moveTrait.moveState!==MoveState.Moving&&e!==t);if(2<e.length||e.find(e=>e.position.subCell===t.position.subCell))return!1}return!(t.zone!==ZoneType.Air&&t.rules.tooBigToFitUnderBridge&&!r&&i.onBridgeLandType&&this.game.map.tileOccupation.getBridgeOnTile(i)?.isHighBridge())&&!(!this.isCancelling()&&this.options?.strictCloseEnough&&void 0!==this.options?.closeEnoughTiles&&!this.isCloseEnoughToDest(t,i,this.options.closeEnoughTiles))}isCloseEnoughToDest(e,t,i){if(void 0===i)return!0;let r=new RangeHelper(this.game.map.tileOccupation);return!(r.tileDistance(this.targetTile,t)>i)}hasReachedDestination(e){return!this.path.length}updateTarget(e,t,i=!1){this.needsPathUpdate=!0,this.targetChangeRequested={tile:e,toBridge:t,onlyIfPathExists:i}}onEnd(e){e.moveTrait.collisionState=CollisionState.Resolved,e.moveTrait.currentWaypoint=void 0,this.targetOffset.equals(this.computeTargetOffset(e))||(e.moveTrait.lastTargetOffset=this.targetOffset)}forceCancel(e){return!(!this.cancellable||this.children.some(e=>!e.cancellable))&&(!(!this.options?.allowOutOfBoundsTarget&&!this.game.map.isWithinBounds(e.tile))&&(this.status!==TaskStatus.Running&&this.status!==TaskStatus.Cancelling||(e.moveTrait.unreservePathNodes(),e.moveTrait.lastMoveResult=MoveResult.Cancel,this.onEnd(e),e.moveTrait.lastTargetOffset=this.targetOffset,e.moveTrait.lastVelocity=e.moveTrait.velocity.clone()),this.status=TaskStatus.Cancelled,!0))}onTick(s){if(s.moveTrait.isDisabled()&&s.moveTrait.moveState===MoveState.ReachedNextWaypoint)return!!this.isCancelling()&&(s.moveTrait.lastMoveResult=MoveResult.Cancel,!0);var e;this.needsPathUpdate&&(s.moveTrait.moveState===MoveState.PlanMove&&(this.inPlanningForTicks=void 0,s.moveTrait.currentWaypoint=void 0,s.moveTrait.collisionState=CollisionState.Resolved,s.moveTrait.moveState=MoveState.ReachedNextWaypoint,s.moveTrait.velocity.set(0,0,0)),e=this.targetTile,r=this.toBridge,this.targetChangeRequested&&(this.targetTile=this.targetChangeRequested.tile,this.toBridge=this.targetChangeRequested.toBridge),this.computePath(s,s.moveTrait.locomotor,this.targetChangeRequested?.onlyIfPathExists)?(this.path.length||this.unreachableTargets.push({tile:this.targetTile,toBridge:this.toBridge}),this.updateDestination(this.path,this.targetOffset),this.allObstaclesAreBlockers=!1):(this.targetTile=e,this.toBridge=r,this.targetLinesConfig.pathNodes=[...this.targetLinesConfig.pathNodes]),this.targetLinesConfig.isRecalc=!this.targetChangeRequested,this.targetChangeRequested=void 0,this.needsPathUpdate=!1);let i=this.game.map;if(s.moveTrait.moveState===MoveState.ReachedNextWaypoint){s.moveTrait.unreservePathNodes();var r=this.path.findIndex(e=>e===s.moveTrait.currentWaypoint);if(-1!==r?this.path.splice(r):this.path.pop(),s.moveTrait.currentWaypoint=void 0,this.isCancelling()?!this.cancelProcessed:this.hasReachedDestination(s)){var a=!this.isCancelling()&&!this.isCloseEnoughToDest(s,s.tile,this.options?.closeEnoughTiles);if(!a&&this.canStopAtTile(s,s.tile,s.onBridge))return s.moveTrait.lastMoveResult=this.isCancelling()?MoveResult.Cancel:MoveResult.Success,!0;{if(this.unreachableTargets.length>MAX_UNREACH_TILES_BAIL)return s.moveTrait.lastMoveResult=MoveResult.Fail,this.log(s,"bail_max_unreachable_dest"),!0;let e=s.tile,t=s.onBridge?i.tileOccupation.getBridgeOnTile(e):void 0;a&&(e=this.targetTile,t=this.toBridge?i.tileOccupation.getBridgeOnTile(e):void 0);r=this.findRelocationTile(e,t,s);if(!r)return s.moveTrait.lastMoveResult=a?MoveResult.Fail:MoveResult.CloseEnough,this.log(s,"bail_no_free_dest"),!0;a=!t||t.isHighBridge()?i.tileOccupation.getBridgeOnTile(r):void 0;return this.updateTarget(r,!!a),this.isCancelling()&&(this.cancelProcessed=!0,this.cancelRepositionPending=!0),!1}}if(this.cancelProcessed&&!this.path.length)return s.moveTrait.lastMoveResult=MoveResult.Cancel,!0;this.cancelProcessed=!1,s.moveTrait.moveState=MoveState.PlanMove;let e=s.moveTrait.locomotor;s.moveTrait.currentWaypoint=e.selectNextWaypoint?e.selectNextWaypoint(s,this.path):this.path[this.path.length-1],this.currentWaypointLeptons.set(s.moveTrait.currentWaypoint.tile.rx,s.moveTrait.currentWaypoint.tile.ry).multiplyScalar(Coords.LEPTONS_PER_TILE).add(this.targetOffset);a=e.onNewWaypoint(s,this.currentWaypointLeptons,this.destinationLeptons);if(a)return this.children.push(...a),!1}if(s.moveTrait.moveState===MoveState.PlanMove){if(this.isCancelling()&&!this.cancelRepositionPending)return s.moveTrait.currentWaypoint=void 0,s.moveTrait.moveState=MoveState.ReachedNextWaypoint,this.onTick(s);if(this.inPlanningForTicks=void 0===this.inPlanningForTicks?0:this.inPlanningForTicks+1,this.inPlanningForTicks>PLANNING_BAILOUT_TICKS)return this.needsPathUpdate=!0,this.allObstaclesAreBlockers=!0,s.moveTrait.velocity.set(0,0,0),this.log(s,"repath_plan_timeout"),!1;if(s.rules.movementZone!==MovementZone.Fly&&!s.moveTrait.locomotor.ignoresTerrain){let t=this.path.slice(this.path.indexOf(s.moveTrait.currentWaypoint)).reverse();var n,o,l,h=s.moveTrait.velocity.length();for(n of t)n.onBridge?.isDestroyed&&(n.onBridge=void 0);for(o of t){if(!i.terrain.getPassableSpeed(o.tile,s.rules.speedType,s.isInfantry(),!!o.onBridge,this.options?.ignoredBlockers))return this.options?.stopOnBlocker&&i.terrain.findObstacles(o,s).some(e=>e.obj===this.options.stopOnBlocker)?(s.moveTrait.lastMoveResult=MoveResult.CloseEnough,!0):(this.needsPathUpdate=!0,s.moveTrait.currentWaypoint=void 0,s.moveTrait.moveState=MoveState.ReachedNextWaypoint,this.onTick(s));if(!o.onBridge){var c=i.getGroundObjectsOnTile(o.tile).find(e=>e.isOverlay()&&e.rules.crate);if(c)if(this.game.crateGeneratorTrait.peekInsideCrate(c)===PowerupType.Unit){this.game.crateGeneratorTrait.pickupCrate(s,c,this.game);c=this.game.map.getGroundObjectsOnTile(o.tile).find(e=>e.isUnit()&&!e.onBridge);if(c)return this.needsPathUpdate=!0,this.blockedPathNodes.push({node:o,obj:c}),s.moveTrait.currentWaypoint=void 0,s.moveTrait.moveState=MoveState.ReachedNextWaypoint,this.onTick(s)}}for(l of i.terrain.findObstacles(o,s).filter(e=>!this.options?.ignoredBlockers?.includes(e.obj))){if(l.static)return this.needsPathUpdate=!0,s.moveTrait.currentWaypoint=void 0,s.moveTrait.moveState=MoveState.ReachedNextWaypoint,this.onTick(s);if(l.obj.rules.crushable){if([SpeedType.Track,SpeedType.Hover].includes(s.rules.speedType)&&s.crusher&&(!l.obj.isTechno()||!this.game.areFriendly(l.obj,s)))continue;if(!l.obj.isTechno())return this.needsPathUpdate=!0,s.moveTrait.currentWaypoint=void 0,s.moveTrait.moveState=MoveState.ReachedNextWaypoint,this.onTick(s)}if(l.obj.isTerrain()){if(!s.isInfantry())throw new Error(`Obstacle ${l.obj.name} should be a blocker for non infantry`);var u=this.findFreeSubCell(s,o);return void 0!==u?this.relocateToSubCell(s,u):(this.needsPathUpdate=!0,this.blockedPathNodes.push({node:o,obj:l.obj}),s.moveTrait.currentWaypoint=void 0,s.moveTrait.moveState=MoveState.ReachedNextWaypoint),this.onTick(s)}if(!l.obj.isTechno())throw new Error("Unexpected obstacle of type "+l.obj.type);const f=l.obj;var d=f.isUnit()?f.moveTrait.velocity.length():0;if(!f.isAircraft()||f.zone!==ZoneType.Ground||!this.options?.ignoredBlockers?.some(e=>e.isBuilding()&&e.dockTrait?.isDocked(f))){if(1===t.length&&f.isUnit()&&d&&h&&h<=d&&s.direction===f.direction&&f.tile===o.tile&&f.moveTrait.currentWaypoint?.tile!==o.tile)break;if(f.isBuilding()||f.moveTrait.moveState===MoveState.Idle||f.moveTrait.collisionState!==CollisionState.Resolved){if(!h&&s.moveTrait.collisionState!==CollisionState.Resolved&&f.isUnit()&&f.moveTrait.collisionState!==CollisionState.Resolved)return this.inPlanningForTicks+1>PLANNING_BAILOUT_TICKS&&(this.needsPathUpdate=!0,this.allObstaclesAreBlockers=!0,this.log(s,"repath_waited_too_long_blocker "+f.id),s.moveTrait.velocity.set(0,0,0)),!1;{if(f.isInfantry()&&s.isInfantry()&&f.moveTrait.collisionState===CollisionState.Resolved){var p=this.findFreeSubCell(s,o);if(void 0!==p)return this.relocateToSubCell(s,p),this.onTick(s)}u=findIndexReverse(this.path.slice(0,this.path.indexOf(o)),e=>!i.terrain.findObstacles(e,s).filter(e=>!this.options?.ignoredBlockers?.includes(e.obj)).length);if(-1===u){if(this.canStopAtTile(s,s.tile,s.onBridge)&&this.isCloseEnoughToDest(s,s.tile,this.options?.closeEnoughTiles))return s.moveTrait.lastMoveResult=MoveResult.CloseEnough,this.log(s,"bail_waypoints_blocked_close_enough"),!0;if(!(0===this.options?.closeEnoughTiles||Math.abs(s.tile.rx-this.targetTile.rx)<=1&&Math.abs(s.tile.ry-this.targetTile.ry)<=1))return this.needsPathUpdate=!0,this.blockedPathNodes.push(...this.path.slice(0,this.path.indexOf(o)+1).map(e=>({node:e,obj:i.terrain.findObstacles(e,s)[0].obj}))),s.moveTrait.velocity.set(0,0,0),this.log(s,"repath_waypoints_blocked_too_far"),!1}let e;if(e=-1!==u?(p=this.path[u],i.terrain.computePath(s.rules.speedType,s.isInfantry(),s.tile,s.onBridge,p.tile,!!p.onBridge,{maxExpandedNodes:15,bestEffort:!1,excludeTiles:e=>!!i.terrain.findObstacles(e,s).filter(e=>!this.options?.ignoredBlockers?.includes(e.obj)).length,ignoredBlockers:this.options?.ignoredBlockers})):[],e.length||f.owner!==s.owner||1!==t.length)return e.length?(this.path.splice(u,this.path.length,...e),s.moveTrait.currentWaypoint=void 0,s.moveTrait.moveState=MoveState.ReachedNextWaypoint,this.onTick(s)):((g=this.selectWeaponVsObstacle(s,f))?(this.children.push(s.attackTrait.createAttackTask(this.game,f,f.tile,g,{passive:!0,holdGround:!0})),s.moveTrait.velocity.set(0,0,0)):this.options?.forceWaitOnPathBlocked?(this.children.push(new WaitTicksTask(MoveTask_RETRY_TICKS)),this.inPlanningForTicks=0,s.moveTrait.velocity.set(0,0,0),s.moveTrait.collisionState=CollisionState.Waiting):(this.needsPathUpdate=!0,this.blockedPathNodes.push({node:o,obj:f}),f.isBuilding()&&(this.allObstaclesAreBlockers=!0),this.log(s,"repath_unavoidable_blocker "+f.id),s.moveTrait.velocity.set(0,0,0)),!1);g=f.unitOrderTrait.hasTasks();if(this.pushTried||f.isBuilding()||f.moveTrait.collisionState===CollisionState.Waiting||g||f.isAircraft()&&f.missileSpawnTrait)return!this.options?.forceWaitOnPathBlocked&&(f.isBuilding()||g&&f.moveTrait.moveState===MoveState.Idle||this.inPlanningForTicks+MoveTask_RETRY_TICKS>PLANNING_BAILOUT_TICKS)?(this.needsPathUpdate=!0,this.allObstaclesAreBlockers=!0,this.log(s,"repath_blocker_busy_wait_timeout "+f.id),s.moveTrait.velocity.set(0,0,0)):(this.children.push(new WaitTicksTask(MoveTask_RETRY_TICKS)),this.options?.forceWaitOnPathBlocked?this.inPlanningForTicks=0:this.inPlanningForTicks+=MoveTask_RETRY_TICKS,s.moveTrait.velocity.set(0,0,0),s.moveTrait.collisionState=CollisionState.Waiting),!1;g=new Vector2(f.tile.rx-s.tile.rx,f.tile.ry-s.tile.ry);return this.pushTried=!0,f.unitOrderTrait.addTask(new MoveAsideTask(this.game,g)),this.children.push(new WaitTicksTask(1)),s.moveTrait.velocity.set(0,0,0),s.moveTrait.collisionState=CollisionState.Waiting,this.log(s,"push "+f.id),!1}}if(f.isInfantry()&&s.isInfantry()){var g=this.findFreeSubCell(s,o);if(void 0!==g)return this.relocateToSubCell(s,g),this.onTick(s)}if(!h)return this.inPlanningForTicks>MoveTask_RETRY_TICKS&&(s.moveTrait.collisionState=CollisionState.Waiting),!1;if(180===Math.abs(s.direction-f.direction))return s.moveTrait.velocity.set(0,0,0),s.moveTrait.collisionState=CollisionState.Waiting,!1;if(Math.abs(s.direction-f.direction)<=45&&h>d*SPEED_MULT){d=this.path.indexOf(o);if(5<=d){let e=findIndexReverse(this.path.slice(0,d-5),e=>!i.terrain.findObstacles(e,s).length);if(-1!==e){d=this.path[e],d=i.terrain.computePath(s.rules.speedType,s.isInfantry(),s.tile,s.onBridge,d.tile,!!d.onBridge,{maxExpandedNodes:15,bestEffort:!1,excludeTiles:t=>!!i.terrain.findObstacles(t,s).length||this.path.findIndex(e=>e.tile===t.tile&&e.onBridge===t.onBridge)>e});if(d.length)return this.path.splice(e,this.path.length,...d),s.moveTrait.currentWaypoint=void 0,s.moveTrait.moveState=MoveState.ReachedNextWaypoint,this.onTick(s)}}return s.moveTrait.collisionState=CollisionState.Waiting,s.moveTrait.velocity.set(0,0,0),!1}return s.moveTrait.velocity.set(0,0,0),s.moveTrait.collisionState=CollisionState.Waiting,!1}}}if(s.rules.speedType===SpeedType.Track&&h){var m,y=this.path.indexOf(s.moveTrait.currentWaypoint);if(0<y){let t=this.path[y-1];for(m of i.getGroundObjectsOnTile(t.tile).filter(e=>e.isUnit()&&e.onBridge===!!t.onBridge&&e.rules.crushable&&e.veteranTrait?.hasVeteranAbility(VeteranAbility.SCATTER)&&!this.game.areFriendly(e,s)))m.unitOrderTrait.hasTasks()||m.unitOrderTrait.addTask(new ScatterTask(this.game))}}s.moveTrait.reservedPathNodes.length||(s.moveTrait.reservedPathNodes.push(...t),t.forEach(e=>{i.tileOccupation.occupySingleTile(e.tile,s)}))}s.moveTrait.moveState=MoveState.Moving,this.inPlanningForTicks=void 0,this.unreachableTargets.length=0,this.pushTried=!1,s.moveTrait.collisionState===CollisionState.Waiting&&(s.moveTrait.collisionState=CollisionState.Resolved)}if(s.moveTrait.moveState===MoveState.Moving){let e=s.moveTrait.locomotor,{distance:t,done:i,isTeleport:r}=e.tick(s,this.currentWaypointLeptons,this.destinationLeptons,(this.isCancelling()||!this.path.length)&&!this.cancelRepositionPending);if(r&&s.traits.filter(NotifyTeleport).forEach(e=>{e[NotifyTeleport.onBeforeTeleport](s,this.game,!0,!0)}),t.length()){a=s.tile,y=e.allowOutOfBounds;if(t.y?(T=s.tileElevation,s.position.moveByLeptons3(t,y),s.moveTrait.handleElevationChange(T,this.game)):s.position.moveByLeptons(t.x,t.z,y),s.tile!==a){var T=s.onBridge?this.game.map.tileOccupation.getBridgeOnTile(a):void 0,y=findReverse(this.path,e=>e.tile===s.tile);let e=y?y.onBridge:T||s.moveTrait.currentWaypoint.onBridge?this.game.map.tileOccupation.getBridgeOnTile(s.tile):void 0;if(e?.isDestroyed&&(e=void 0),s.moveTrait.handleTileChange(a,e,!1,this.game,r),r&&(s.moveTrait.lastTeleportTick=this.game.currentTick,this.game.events.dispatch(new ObjectTeleportEvent(s,!0,a))),s.isDestroyed)return!0}}if(i)return s.moveTrait.moveState=MoveState.ReachedNextWaypoint,this.onTick(s)}return!1}selectWeaponVsObstacle(e,t){let i;if(!this.game.areFriendly(t,e)&&e.attackTrait&&!e.attackTrait.isDisabled()&&e.attackTrait.isIdle()&&(i=e.attackTrait.selectWeaponVersus(e,t,this.game,!1,!0))&&i.name!==e.armedTrait?.deathWeapon?.name&&(!i.rules.limboLaunch||!i.warhead.rules.parasite)&&!i.warhead.rules.mindControl)return i}findRelocationTile(a,n,o){let l=this.game.map,i;if(o.rules.movementZone===MovementZone.Fly){var t=e=>!l.tileOccupation.getGroundObjectsOnTile(e).some(e=>e.isBuilding()&&!e.isDestroyed||e.isTerrain()||e.isOverlay()&&e.rules.isARock)&&(o.rules.locomotor!==LocomotorType.Jumpjet||0<this.game.map.terrain.getPassableSpeed(e,SpeedType.Amphibious,o.isInfantry(),!!e.onBridgeLandType));let e=new RandomTileFinder(l.tiles,l.mapBounds,a,1,this.game,t);if(i=e.getNextTile(),!i){let e=new RadialTileFinder(l.tiles,l.mapBounds,a,o.getFoundation(),2,15,t);i=e.getNextTile()}}else{let e=!this.options?.ignoredBlockers?.length&&l.terrain.getPassableSpeed(o.tile,o.rules.speedType,o.isInfantry(),o.onBridge)?this.game.map.terrain.getIslandIdMap(o.rules.speedType,o.isInfantry()):void 0,r=e?.get(o.tile,o.onBridge),s=new MovePositionHelper(l),t=new RadialTileFinder(l.tiles,l.mapBounds,a,{width:1,height:1},0,5,t=>{let i=!n||n.isHighBridge()?l.tileOccupation.getBridgeOnTile(t):void 0;return!this.unreachableTargets.find(e=>e.tile===t&&e.toBridge===!!i)&&(o.zone===ZoneType.Air||e?.get(t,!!i)===r&&!l.terrain.findObstacles({tile:t,onBridge:i},o).length&&s.isEligibleTile(t,i,n,a))&&this.canStopAtTile(o,t,!!i)});i=t.getNextTile()}return i}findFreeSubCell(t,i){let e=this.game.map.getGroundObjectsOnTile(i.tile);var r=e.filter(e=>e.isInfantry()&&e.onBridge===!!i.onBridge&&e!==t).map(e=>e.position.desiredSubCell),s=e.filter(e=>e.isTerrain()).map(e=>e.rules.getOccupiedSubCells(this.game.map.getTheaterType())).flat();let a=[...r,...s];return Infantry_Infantry.SUB_CELLS.find(e=>-1===a.indexOf(e))}relocateToSubCell(e,t){e.position.desiredSubCell=t;t=e.position.computeSubCellOffset(t);this.targetOffset=t,this.currentWaypointLeptons.set(e.moveTrait.currentWaypoint.tile.rx,e.moveTrait.currentWaypoint.tile.ry).multiplyScalar(Coords.LEPTONS_PER_TILE).add(this.targetOffset),this.updateDestination(this.path,this.targetOffset),e.moveTrait.locomotor.onWaypointUpdate?.(e,this.currentWaypointLeptons,this.destinationLeptons)}getTargetLinesConfig(e){var t,i;return this.path||(t=new LocomotorFactory(this.game).create(e),(this.options?.allowOutOfBoundsTarget||this.game.map.mapBounds.isWithinBounds(this.targetTile))&&e.rules.movementZone!==MovementZone.Fly&&!t.ignoresTerrain&&e.unitOrderTrait.getCurrentTask()?.isCancelling()?this.groundPathPlan||(i=this.computeGroundPath(e),this.targetLinesConfig.pathNodes=i.path,i.path.length&&(this.groundPathPlan=i)):((i=e.moveTrait).locomotor??(i.locomotor=t),this.computePath(e,e.moveTrait.locomotor)),this.targetLinesConfig.isRecalc=!1),this.targetLinesConfig}log(e,t){this.logger.debug(`<${e.id}>: `+t)}}(NotifyDestroy=NotifyDestroy||{}).onDestroy=Symbol(),function(e){e[e.None=0]="None",e[e.Normal=1]="Normal",e[e.Demolish=2]="Demolish",e[e.Crush=3]="Crush",e[e.Temporal=4]="Temporal",e[e.Sink=5]="Sink"}(DeathType=DeathType||{}),(NotifyTileChange=NotifyTileChange||{}).onTileChange=Symbol(),(NotifyTileChange_NotifyTileChange=NotifyTileChange_NotifyTileChange||{}).onTileChange=Symbol();class EnterTileEvent{constructor(e,t){this.target=e,this.source=t,this.type=EventType.EnterTile}}(NotifyElevationChange=NotifyElevationChange||{}).onElevationChange=Symbol(),function(e){e[e.Idle=0]="Idle",e[e.ReachedNextWaypoint=1]="ReachedNextWaypoint",e[e.PlanMove=2]="PlanMove",e[e.Moving=3]="Moving"}(MoveState=MoveState||{}),function(e){e[e.Success=0]="Success",e[e.Cancel=1]="Cancel",e[e.CloseEnough=2]="CloseEnough",e[e.Fail=3]="Fail"}(MoveResult=MoveResult||{}),function(e){e[e.Waiting=0]="Waiting",e[e.Resolved=1]="Resolved"}(CollisionState=CollisionState||{});const findMoveTaskDeep=e=>e instanceof MoveTask||e.children[0]&&findMoveTaskDeep(e.children[0]);class MoveTrait{get baseSpeed(){return this.gameObject.rules.speed*(this.gameObject.veteranTrait?.getVeteranSpeedMultiplier()??1)*this.gameObject.crateBonuses.speed*(this.gameObject.isVehicle()&&this.gameObject.healthTrait.health<=50&&this.gameObject.rules.locomotor!==LocomotorType.Hover?.75:1)*(1-this.speedPenalty)}constructor(e,t){this.gameObject=e,this.tileOccupation=t,this.disabled=!1,this.speedPenalty=0,this.velocity=new Vector3_Vector3,this.reservedPathNodes=[],this.moveState=MoveState.Idle,this.collisionState=CollisionState.Resolved}isDisabled(){return this.disabled}setDisabled(e){this.disabled=e}isMoving(){return this.moveState===MoveState.Moving}isIdle(){return this.moveState===MoveState.Idle}isWaiting(){return this.collisionState===CollisionState.Waiting}[NotifyTick_NotifyTick.onTick](e,t){var i;this.moveState!==MoveState.Idle&&this.collisionState===CollisionState.Resolved&&((i=e.unitOrderTrait.getCurrentTask())&&findMoveTaskDeep(i)||(this.velocity.set(0,0,0),this.moveState=MoveState.Idle,this.locomotor=void 0,!i&&!e.attackTrait?.currentTarget&&e.isVehicle()&&e.turretTrait&&(e.turretTrait.desiredFacing=e.direction))),this.moveState===MoveState.Idle&&(e.rules.locomotor===LocomotorType.Jumpjet?JumpjetLocomotor.tickStationary(e,t):e.isAircraft()&&e.rules.locomotor===LocomotorType.Aircraft&&WingedLocomotor.tickStationary(e,t))}[NotifyDestroy.onDestroy](e,t){this.unreservePathNodes()}teleportUnitToTile(e,t,i,r,s){let a=this.gameObject;var n=a.tile;a.traits.filter(NotifyTeleport).forEach(e=>{e[NotifyTeleport.onBeforeTeleport](a,s,i,r)}),a.position.tileElevation=a.tileElevation,a.position.tile=e,a.position.subCell=a.position.desiredSubCell,this.handleTileChange(n,t,!0,s,!0),r||(this.unreservePathNodes(),this.speedPenalty=0,this.velocity.set(0,0,0),this.moveState=MoveState.Idle,this.collisionState=CollisionState.Resolved,this.locomotor=void 0,this.currentWaypoint=void 0,this.lastTargetOffset=void 0,this.lastVelocity=void 0,this.lastMoveResult=MoveResult.Cancel,a.isVehicle()&&(a.spinVelocity=0,a.turretTrait&&(a.turretTrait.desiredFacing=a.direction))),this.lastTeleportTick=s.currentTick,s.events.dispatch(new ObjectTeleportEvent(a,i,n))}handleTileChange(t,e,i,r,s=!1){const a=this.gameObject;if(r.map.tileOccupation.unoccupyTileRange(t,a),r.map.tileOccupation.occupyTileRange(a.tile,a),r.map.technosByTile.updateObject(a),a.zone!==ZoneType.Air){var n=a.onBridge?r.map.tileOccupation.getBridgeOnTile(t):void 0,o=a.onBridge?t.onBridgeLandType:t.landType,l=e?a.tile.onBridgeLandType:a.tile.landType;o!==l&&(0<r.rules.getLandRules(l).getSpeedModifier(a.rules.speedType)||a.rules.speedType===SpeedType.Amphibious||s)&&(a.zone=getZoneType(l)),e!==n&&(a.position.tileElevation+=-(n?.tileElevation??0)+(e?.tileElevation??0),a.onBridge=!!e);var h,e=a.moveTrait.reservedPathNodes.findIndex(e=>e.tile===a.tile);if(-1!==e&&a.moveTrait.reservedPathNodes.splice(e,1),a.crusher)for(h of r.map.getGroundObjectsOnTile(a.tile).filter(e=>(!e.isUnit()||e.onBridge===a.onBridge)&&e.rules.crushable&&!(e.isInfantry()&&e.stance===StanceType.Paradrop)&&(!(e.isTechno()&&!i)||!r.areFriendly(e,a))))h.isDestroyed||(h.isInfantry()&&(h.infDeathType=InfDeathType.None),a.isVehicle()&&h.isOverlay()&&h.rules.wall&&a.applyRocking(0,.5),h.deathType=DeathType.Crush,r.destroyObject(h,{player:a.owner,obj:a}));a.onBridge||(e=r.map.tileOccupation.getGroundObjectsOnTile(a.tile).find(e=>e.isOverlay()&&e.rules.crate))&&r.crateGeneratorTrait.pickupCrate(a,e,r)}r.traits.filter(NotifyTileChange).forEach(e=>{e[NotifyTileChange.onTileChange](a,r,t,s)}),a.traits.filter(NotifyTileChange_NotifyTileChange).forEach(e=>{e[NotifyTileChange_NotifyTileChange.onTileChange](a,r,t,s)}),r.events.dispatch(new EnterTileEvent(a.tile,a))}handleElevationChange(t,i){i.traits.filter(NotifyElevationChange).forEach(e=>{e[NotifyElevationChange.onElevationChange](this.gameObject,i,t)})}unreservePathNodes(){this.reservedPathNodes.forEach(e=>{e.tile!==this.gameObject.tile&&this.tileOccupation.unoccupySingleTile(e.tile,this.gameObject)}),this.reservedPathNodes.length=0}dispose(){this.gameObject=void 0}}class SuppressionTrait{constructor(){this.suppressionTicks=0,this.enabled=!0}disable(){this.enabled=!1}isSuppressed(){return this.enabled&&0<this.suppressionTicks}suppress(){this.enabled&&(this.suppressionTicks=30)}[NotifyTick_NotifyTick.onTick](){0<this.suppressionTicks&&this.suppressionTicks--}}class Traits{constructor(){this.allTraits=[],this.traitsByTypeCache=new Map}add(e){this.allTraits.push(e),this.traitsByTypeCache.clear()}addToFront(e){this.allTraits.unshift(e),this.traitsByTypeCache.clear()}remove(e){e=this.allTraits.indexOf(e);-1!==e&&(this.allTraits.splice(e,1),this.traitsByTypeCache.clear())}filter(t){let e=this.traitsByTypeCache.get(t);return e||(e="function"==typeof t?this.allTraits.filter(e=>e instanceof t):this.allTraits.filter(e=>this.traitImplements(e,t)),this.traitsByTypeCache.set(t,e)),e}get(e){e=this.find(e);if(!e)throw new Error("No matching trait found");return e}find(e){return this.filter(e)[0]}getAll(){return this.allTraits}traitImplements(e,t){for(var i of Object.getOwnPropertyNames(t))if(void 0===e[t[i]])return!1;return!0}clear(){this.allTraits.length=0,this.traitsByTypeCache.clear()}dispose(){this.getAll().forEach(e=>e.dispose?.()),this.clear()}}(NotifyOwnerChange=NotifyOwnerChange||{}).onChange=Symbol(),(NotifySpawn=NotifySpawn||{}).onSpawn=Symbol(),(NotifyUnspawn=NotifyUnspawn||{}).onUnspawn=Symbol(),(NotifyAttack=NotifyAttack||{}).onAttack=Symbol();class GameObject{get tile(){return this.position.tile}get tileElevation(){return this.position.tileElevation}constructor(e,t,i,r){this.traits=new Traits,this.cachedTraits={tick:[]},this.isCrashing=!1,this.isDestroyed=!1,this.deathType=DeathType.Normal,this.isDisposed=!1,this.isSpawned=!1,this.type=e,this.name=t,this.rules=i,this.art=r}getFoundation(){return{width:1,height:1}}isSmudge(){return this.type===ObjectType.Smudge}isOverlay(){return this.type===ObjectType.Overlay}isTerrain(){return this.type===ObjectType.Terrain}isProjectile(){return this.type===ObjectType.Projectile}isDebris(){return this.type===ObjectType.Debris}isBuilding(){return!1}isInfantry(){return!1}isVehicle(){return!1}isAircraft(){return!1}isUnit(){return!1}isTechno(){return!1}update(e){for(var t of this.cachedTraits.tick)t[NotifyTick_NotifyTick.onTick](this,e)}onSpawn(t){this.isSpawned=!0,this.traits.filter(NotifySpawn).forEach(e=>{e[NotifySpawn.onSpawn](this,t)})}onUnspawn(t){this.isSpawned=!1,this.traits.filter(NotifyUnspawn).forEach(e=>{e[NotifyUnspawn.onUnspawn](this,t)})}onDestroy(t,i,r){this.traits.filter(NotifyDestroy).forEach(e=>{e[NotifyDestroy.onDestroy](this,t,i,r)})}onOwnerChange(t,i){this.traits.filter(NotifyOwnerChange).forEach(e=>{e[NotifyOwnerChange.onChange](this,t,i)})}onAttack(t,i){this.traits.filter(NotifyAttack).forEach(e=>{e[NotifyAttack.onAttack](this,i,t)})}addTrait(e){this.traits.add(e),e[NotifyTick_NotifyTick.onTick]&&this.cachedTraits.tick.push(e)}getUiName(){return this.rules.uiName}getHash(){var e=this.position.worldPosition;return fnv32a([this.id,...new Uint8Array(new Float64Array([e.x,e.y,e.z]).buffer),...this.traits.getAll().map(e=>e.getHash?.()??0)])}debugGetState(){return{id:this.id,position:this.position.worldPosition.toArray(),traits:this.traits.getAll().reduce((e,t)=>{var i=t.debugGetState?.();return void 0!==i&&(e[t.constructor.name]=i),e},{})}}dispose(){this.isDisposed=!0,this.traits.dispose(),this.cachedTraits.tick.length=0}}!function(e){e[e.None=0]="None",e[e.Veteran=1]="Veteran",e[e.Elite=2]="Elite"}(VeteranLevel=VeteranLevel||{});class Techno_Techno extends GameObject{get primaryWeapon(){return this.armedTrait?.primaryWeapon}get secondaryWeapon(){return this.armedTrait?.secondaryWeapon}get ammo(){return this.ammoTrait?.ammo}get sight(){return Math.min(TechnoRules.MAX_SIGHT,this.rules.sight*(this.veteranTrait?.getVeteranSightMultiplier()??1))}get veteranLevel(){return this.veteranTrait?.veteranLevel??VeteranLevel.None}constructor(e,t,i,r){super(e,t,i,r),this.explodes=this.rules.explodes,this.radarInvisible=this.rules.radarInvisible,this.c4=this.rules.c4,this.crusher=this.rules.crusher,this.defaultToGuardArea=this.rules.defaultToGuardArea,this.guardMode=this.rules.defaultToGuardArea,this.purchaseValue=this.rules.cost}resetGuardModeToIdle(){this.guardMode=this.defaultToGuardArea,this.guardArea=void 0}update(e){if(this.warpedOutTrait.isActive())for(var t of this.cachedTraits.tick)t.ticksWhenWarpedOut&&t[NotifyTick_NotifyTick.onTick](this,e);else super.update(e)}isTechno(){return!0}}class IdleActionTrait{constructor(){this.cooldownTicks=Number.POSITIVE_INFINITY,this._actionDueThisTick=!1}[NotifyTick_NotifyTick.onTick](e,t){this._actionDueThisTick=!1;var i=!e.unitOrderTrait.hasTasks();i&&!this.idle?this.resetCooldown(t):i?0===this.cooldownTicks?(this.doIdleAction(e,t),this.resetCooldown(t)):this.cooldownTicks--:this.cooldownTicks=Number.POSITIVE_INFINITY,this.idle=i}doIdleAction(e,t){if(e.isInfantry()){if(e.rules.fraidycat)if(e.owner.isNeutral&&.5<t.generateRandom())return void e.unitOrderTrait.addTask(new ScatterTask(t,void 0,{noSlopes:!0}));this._actionDueThisTick=!0}}actionDueThisTick(){return this._actionDueThisTick}resetCooldown(e){var t=e.rules.audioVisual.idleActionFrequency,e=e.generateRandom()*t*.5,e=Math.max(0,t-e);this.cooldownTicks=Math.floor(e*GameSpeed.BASE_TICKS_PER_SECOND)}}class ObjectCrashingEvent{constructor(e){this.gameObject=e,this.type=EventType.ObjectCrashing}}(NotifyCrash=NotifyCrash||{}).onCrash=Symbol();class CrashableTrait{constructor(e){this.gameObject=e,this.crashingEvtSent=!1,this.crashState={}}[NotifyTick_NotifyTick.onTick](i,r){if(i.isCrashing){if(this.crashingEvtSent||(this.crashingEvtSent=!0,i.traits.filter(NotifyCrash).forEach(e=>e[NotifyCrash.onCrash](i,r)),r.events.dispatch(new ObjectCrashingEvent(i))),i.rules.locomotor!==LocomotorType.Jumpjet&&i.rules.locomotor!==LocomotorType.Aircraft)throw new Error("Crashing logic not implemented for locomotor "+LocomotorType[i.rules.locomotor]);{let e;if(i.rules.locomotor===LocomotorType.Jumpjet)e=JumpjetLocomotor.tickCrash(i,r,this.crashState);else{if(i.rules.locomotor!==LocomotorType.Aircraft)throw new Error(`Unhandled locomotor type "${i.rules.locomotor}"`);if(!i.isAircraft())throw new Error(`Obj "${i.name}#${i.id} is not an aircraft`);e=WingedLocomotor.tickCrash(i,r,this.crashState)}let t=!1;var s,a,n=e.clone().add(i.position.worldPosition);r.map.isWithinHardBounds(n)?(a=i.tile,s=i.tileElevation,i.position.moveByLeptons3(e),i.tile!==a&&i.moveTrait.handleTileChange(a,void 0,!1,r),a=(n=i.tile.onBridgeLandType?r.map.tileOccupation.getBridgeOnTile(i.tile):void 0)?.tileElevation??0,i.position.tileElevation=Math.max(i.position.tileElevation,a),i.position.tileElevation===a&&(i.zone=r.map.getTileZone(i.tile),i.onBridge=!!n,t=!0),i.tileElevation!==s&&i.moveTrait.handleElevationChange(s,r)):t=!0,t&&r.destroyObject(i,this.attackerInfo)}}}crash(e){this.attackerInfo=e,this.gameObject.isCrashing=!0,this.gameObject.cachedTraits.tick.length=0,this.gameObject.cachedTraits.tick=[this]}dispose(){this.gameObject=void 0}}class AgentTrait{infiltrate(e,t,i){var r;t.rules.radar&&![...t.owner.buildings].some(e=>e.rules.spySat)&&i.mapShroudTrait.resetShroud(t.owner,i),0<t.rules.power&&(r=i.rules.general.spyPowerBlackout,t.owner.powerTrait?.setBlackoutFor(r,i)),t.superWeaponTrait&&t.superWeaponTrait.getSuperWeapon(t)?.resetTimer(),0<t.rules.storage&&(r=clamp(i.rules.general.spyMoneyStealPercent,0,1),r=Math.floor(t.owner.credits*r),t.owner.credits-=r,e.owner.credits+=r),!i.rules.ai.buildTech.includes(t.name)||void 0!==(i=t.rules.aiBasePlanningSide)&&e.owner.production.addStolenTech(i),t.factoryTrait&&[FactoryType.InfantryType,FactoryType.UnitType].includes(t.factoryTrait.type)&&e.owner.production?.addVeteranType(t.factoryTrait.type)}}class CrateBonuses{constructor(){this.firepower=1,this.armor=1,this.speed=1}}class Infantry_Infantry extends Techno_Techno{get isMoving(){return this.moveTrait.isMoving()}static factory(e,t,i,r){let s=new this(e,t,i);return s.moveTrait=new MoveTrait(s,r),s.traits.add(s.moveTrait),s.rules.crashable&&(s.crashableTrait=new CrashableTrait(s),s.traits.add(s.crashableTrait)),s.rules.fearless||(s.suppressionTrait=new SuppressionTrait,s.traits.add(s.suppressionTrait)),s.rules.agent&&(s.agentTrait=new AgentTrait,s.traits.add(s.agentTrait)),s.idleActionTrait=new IdleActionTrait,s.traits.add(s.idleActionTrait),s}constructor(e,t,i){super(ObjectType.Infantry,e,t,i),this.direction=0,this.onBridge=!1,this.zone=ZoneType.Ground,this._stance=StanceType.None,this.isFiring=!1,this.isPanicked=!1,this.infDeathType=InfDeathType.Gunfire,this.crateBonuses=new CrateBonuses}get stance(){return this._stance===StanceType.None&&this.suppressionTrait?.isSuppressed()?StanceType.Prone:this._stance}set stance(e){this._stance=e,this.moveTrait.setDisabled([StanceType.Deployed,StanceType.Cheer].includes(e)),this.attackTrait?.setDisabled([StanceType.Paradrop,StanceType.Cheer].includes(e))}isUnit(){return!0}isInfantry(){return!0}}Infantry_Infantry.SUB_CELLS=[2,4,3];class ParadropTask extends Task{constructor(e){super(),this.game=e}onTick(e){var t=Math.abs(this.game.rules.general.parachuteMaxFallRate),i=e.tile.onBridgeLandType?this.game.map.tileOccupation.getBridgeOnTile(e.tile).tileElevation:0,r=Coords.tileHeightToWorld(i),s=e.tileElevation,a=Coords.tileHeightToWorld(s);return r<Math.max(r,a-t)?(e.position.moveByLeptons3(new Vector3_Vector3(0,-t,0)),e.moveTrait.handleElevationChange(s,this.game),!1):(e.position.tileElevation=i,e.stance=StanceType.None,this.game.map.terrain.getPassableSpeed(e.tile,e.rules.speedType,e.isInfantry(),e.onBridge)||(e.infDeathType=InfDeathType.None,this.game.destroyObject(e,void 0,!0)),!0)}}function bresenham(i,r,s,a,n){let o=[];n=n||((e,t)=>{o.push({x:e,y:t})});var e=s-i,t=a-r,l=Math.abs(e),h=Math.abs(t);let c=0;var u=0<e?1:-1,d=0<t?1:-1;if(h<l)for(let e=i,t=r;u<0?e>=s:e<=s;e+=u)n(e,t),c+=h,c<<1>=l&&(t+=d,c-=l);else for(let e=i,t=r;d<0?t>=a:t<=a;t+=d)n(e,t),c+=l,c<<1>=h&&(e+=u,c-=h);return o}function isNotNullOrUndefined(e){return null!=e}class TaskGroup extends Task{constructor(...e){super(),this.children.push(...e)}onTick(e){return!0}}class UnlandableTrait{constructor(){this.enabled=!0}setEnabled(e){this.enabled=e}[NotifyTick_NotifyTick.onTick](e,t){var i;this.enabled&&(e.owner.isNeutral||e.name===t.rules.general.paradrop.paradropPlane)&&e.unitOrderTrait.isIdle()&&(i=this.chooseExitTile(e.tile,t),e.unitOrderTrait.addTask(new TaskGroup(new MoveTask(t,i,!1,{allowOutOfBoundsTarget:!0}),new CallbackTask(e=>t.unspawnObject(e))).setCancellable(!1)))}chooseExitTile(e,t){var i=t.map.tiles.getMapSize(),i=.5<t.generateRandom()?new Vector2(Math.floor(i.width/2),0):new Vector2(0,Math.floor(i.height/2)),e=new Vector2(e.rx,e.ry),i=bresenham(e.x,e.y,i.x,i.y).map(e=>t.map.tiles.getByMapCoords(e.x,e.y)).filter(isNotNullOrUndefined);if(!i.length)throw new Error("No valid exit tile found");return i[i.length-1]}}!function(e){e[e.Spawning=0]="Spawning",e[e.EnRoute=1]="EnRoute",e[e.Dropping=2]="Dropping",e[e.TurningAround=3]="TurningAround"}(ParadropState=ParadropState||{});const PLANE_SPAWN_DELAY_FRAMES=5*GameSpeed.BASE_TICKS_PER_SECOND,MAX_FAILED_ATTEMPTS=5;class ParadropEffect extends SuperWeaponEffect{constructor(e,t,i,r,s){super(e,t,i),this.paradropSquad=r,this.state=ParadropState.Spawning,this.failedAttempts=0,this.spawnDelay=s*PLANE_SPAWN_DELAY_FRAMES}onStart(e){this.passengerRules=e.rules.getObject(this.paradropSquad.inf,ObjectType.Infantry),this.passengerCount=this.paradropSquad.num}computeFlightPath(e,t,i){if(t.equals(e))throw new Error("Source and destination must be different");let r=e.clone().sub(t);e=i.rules.general.paradrop.paradropRadius/Coords.LEPTONS_PER_TILE,e=t.clone().add(r.clone().setLength(r.length()+2*e)).floor();let s=bresenham(t.x,t.y,e.x,e.y).map(e=>i.map.tiles.getByMapCoords(e.x,e.y)??i.map.tiles.getPlaceholderTile(e.x,e.y));for(;s.length;){var a=s[0],a=Coords.tileToWorld(a.rx+.5,a.ry+.5);if(i.map.isWithinHardBounds(new Vector2(a.x,a.y)))break;s.shift()}if(!s.length)throw new Error("No valid paradrop path found");return{fromTile:s[0],toTile:s[s.length-1]}}onTick(s){if(this.state===ParadropState.Spawning){if(0<this.spawnDelay)return this.spawnDelay--,!1;var a=s.map.tiles.getMapSize(),n=[new Vector2(0,0),new Vector2(Math.floor(a.width/2),0),new Vector2(0,Math.floor(a.height/2))][s.generateRandomInt(0,2)];let t=this.passengerRules.speedType,e=new RadialTileFinder(s.map.tiles,s.map.mapBounds,this.tile,{width:1,height:1},0,50,e=>0<s.map.terrain.getPassableSpeed(e,t,!0,!!e.onBridgeLandType));var o=this.targetTile=e.getNextTile();if(!o)return!0;let i=new Vector2(o.rx,o.ry);var{fromTile:l,toTile:a}=this.computeFlightPath(i,n,s),o=s.rules.general.paradrop.paradropPlane,n=s.rules.getObject(o,ObjectType.Aircraft);let r=this.pdPlane=s.createUnitForPlayer(n,this.owner);s.spawnObject(r,l),r.direction=FacingUtil.fromMapCoords(i.clone().sub(new Vector2(l.rx,l.ry))),r.position.tileElevation=Coords.worldToTileHeight(r.rules.flightLevel??s.rules.general.flightLevel),r.zone=ZoneType.Air,r.onBridge=!1,r.unitOrderTrait.addTask(new MoveTask(s,a,!1,{allowOutOfBoundsTarget:!0})),r.traits.get(UnlandableTrait).setEnabled(!1),this.state=ParadropState.EnRoute}if(!this.pdPlane||this.pdPlane.isDestroyed||this.pdPlane.isCrashing)return!0;o=this.targetTile;if(!this.pdPlane.unitOrderTrait.hasTasks())return this.state=ParadropState.TurningAround,this.pdPlane.unitOrderTrait.addTask(new MoveTask(s,o,!1,{allowOutOfBoundsTarget:!0})),!1;n=s.rules.general.paradrop.paradropRadius/Coords.LEPTONS_PER_TILE;let e=new RangeHelper(s.map.tileOccupation);l=e.isInTileRange(this.pdPlane.tile,o,0,n);if(this.state===ParadropState.EnRoute&&l&&(this.state=ParadropState.Dropping),this.state===ParadropState.Dropping)if(l&&0<this.passengerCount){a=this.pdPlane.tile;let t=!!a.onBridgeLandType;if(this.failedAttempts>MAX_FAILED_ATTEMPTS&&s.map.mapBounds.isWithinBounds(a))return this.passengerCount=0,!1;if(!s.map.terrain.getPassableSpeed(a,this.passengerRules.speedType,!0,t))return!1;let e=s.map.getGroundObjectsOnTile(a);if(e.some(e=>e.isVehicle()&&e.onBridge===t||e.isBuilding()&&!e.isDestroyed||e.isInfantry()&&e.stance===StanceType.Paradrop))return!1;n=this.findFreeSubCell(s,a);if(!n)return!1;this.passengerCount--;let i=s.createUnitForPlayer(this.passengerRules,this.owner);i.stance=StanceType.Paradrop,i.position.tileElevation=this.pdPlane.tileElevation,i.position.subCell=n,i.onBridge=t,i.rules.trainable&&this.owner.canProduceVeteran(i.rules)&&i.veteranTrait?.setVeteranLevel(VeteranLevel.Veteran),s.spawnObject(i,a),i.unitOrderTrait.addTask(new ParadropTask(s).setCancellable(!1))}else{if(!(0<this.passengerCount))return this.pdPlane.unitOrderTrait.getCurrentTask().forceCancel(this.pdPlane),this.pdPlane.traits.get(UnlandableTrait).setEnabled(!0),!0;this.failedAttempts++,this.state=ParadropState.TurningAround,this.pdPlane.unitOrderTrait.getCurrentTask().updateTarget(o,!!o.onBridgeLandType)}return this.state===ParadropState.TurningAround&&l&&(o=this.computeFlightPath(new Vector2(o.rx,o.ry),new Vector2(this.pdPlane.tile.rx,this.pdPlane.tile.ry),s)["toTile"],this.pdPlane.unitOrderTrait.getCurrentTask().updateTarget(o,!1),this.state=ParadropState.EnRoute),!1}findFreeSubCell(t,e){let i=t.map.getGroundObjectsOnTile(e).filter(e=>e.isTerrain()).map(e=>e.rules.getOccupiedSubCells(t.map.getTheaterType())).flat();e=Infantry_Infantry.SUB_CELLS.filter(e=>-1===i.indexOf(e));if(e.length)return 1<e.length?e[t.generateRandomInt(0,e.length-1)]:e[0]}}!function(e){e[e.NotBridge=0]="NotBridge",e[e.Concrete=1]="Concrete",e[e.Wood=2]="Wood"}(OverlayBridgeType=OverlayBridgeType||{});class BridgeOverlayTypes{static getOverlayBridgeType(e){return isBetween(e,this.minHighBridgeConcreteId,this.maxHighBridgeConcreteId)||isBetween(e,this.minLowBridgeConcreteId,this.maxLowBridgeConcreteId)?OverlayBridgeType.Concrete:isBetween(e,this.minHighBridgeWoodId,this.maxHighBridgeWoodId)||isBetween(e,this.minLowBridgeWoodId,this.maxLowBridgeWoodId)?OverlayBridgeType.Wood:OverlayBridgeType.NotBridge}static isBridge(e){return this.isHighBridge(e)||this.isLowBridge(e)}static isBridgePlaceholder(e){return this.bridgePlaceholderIds.includes(e)}static isHighBridge(e){return isBetween(e,this.minHighBridgeWoodId,this.maxHighBridgeWoodId)||isBetween(e,this.minHighBridgeConcreteId,this.maxHighBridgeConcreteId)}static isLowBridge(e){return isBetween(e,this.minLowBridgeWoodId,this.maxLowBridgeWoodId)||isBetween(e,this.minLowBridgeConcreteId,this.maxLowBridgeConcreteId)}static isXBridge(e){return e===this.minHighBridgeWoodId||e===this.minHighBridgeConcreteId||isBetween(e,this.minLowBridgeWoodId,this.minLowBridgeWoodId+8)||isBetween(e,this.minLowBridgeWoodId+18,this.minLowBridgeWoodId+21)||isBetween(e,this.minLowBridgeConcreteId,this.minLowBridgeConcreteId+8)||isBetween(e,this.minLowBridgeConcreteId+18,this.minLowBridgeConcreteId+21)}static isLowBridgeHead(e){return isBetween(e,this.minLowBridgeWoodId+18,this.minLowBridgeWoodId+25)||isBetween(e,this.minLowBridgeConcreteId+18,this.minLowBridgeConcreteId+25)}static isLowBridgeHeadStart(e){return isBetween(e,this.minLowBridgeWoodId+20,this.minLowBridgeWoodId+23)||isBetween(e,this.minLowBridgeConcreteId+20,this.minLowBridgeConcreteId+23)}static calculateLowBridgeOverlayId(e,t){let i;if(e===OverlayBridgeType.Concrete)i=this.minLowBridgeConcreteId;else{if(e!==OverlayBridgeType.Wood)throw new Error("Not implemented");i=this.minLowBridgeWoodId}return i+(t?0:9)}static calculateHighBridgeOverlayId(e,t){let i;if(e===OverlayBridgeType.Concrete)i=this.minHighBridgeConcreteId;else{if(e!==OverlayBridgeType.Wood)throw new Error("Not implemented");i=this.minHighBridgeWoodId}return i+(t?0:1)}}BridgeOverlayTypes.minLowBridgeWoodId=74,BridgeOverlayTypes.maxLowBridgeWoodId=99,BridgeOverlayTypes.minLowBridgeConcreteId=205,BridgeOverlayTypes.maxLowBridgeConcreteId=230,BridgeOverlayTypes.minHighBridgeConcreteId=24,BridgeOverlayTypes.maxHighBridgeConcreteId=25,BridgeOverlayTypes.minHighBridgeWoodId=237,BridgeOverlayTypes.maxHighBridgeWoodId=238,BridgeOverlayTypes.bridgePlaceholderIds=[100,101,231,232],(NotifyAttack_NotifyAttack=NotifyAttack_NotifyAttack||{}).onAttack=Symbol(),function(e){e[e.None=0]="None",e[e.Ground=1]="Ground",e[e.Wall=2]="Wall",e[e.Cliff=3]="Cliff",e[e.OnBridge=4]="OnBridge",e[e.UnderBridge=5]="UnderBridge",e[e.Shore=6]="Shore"}(CollisionType=CollisionType||{});class WarheadDetonateEvent{constructor(e,t,i,r){this.target=e,this.position=t,this.explodeAnim=i,this.isLightningStrike=r,this.type=EventType.WarheadDetonate}}!function(e){e[e.Top=0]="Top",e[e.TopLeft=1]="TopLeft",e[e.TopRight=2]="TopRight",e[e.Left=3]="Left",e[e.Right=4]="Right",e[e.BottomLeft=5]="BottomLeft",e[e.Bottom=6]="Bottom",e[e.BottomRight=7]="BottomRight"}(TileDirection=TileDirection||{});class TileCollection{constructor(i,r,e,s){this.tileSets=r,this.generalRules=e;let a=this.rSize={width:0,height:0},n=this.dSize={width:0,height:0};for(let e=0,t=i.length;e<t;++e)a.width=Math.max(a.width,i[e].rx),a.height=Math.max(a.height,i[e].ry),n.width=Math.max(n.width,i[e].dx),n.height=Math.max(n.height,i[e].dy);a.width++,a.height++,n.width++,n.height++;let o=this.tilesByRxy=new Array(a.width*a.height);o.fill(void 0);let l=this.tilesByDxy=new Array(n.width*n.height);l.fill(void 0);let h=this.tiles=new Array(i.length),c=[],u=this.bridgeSetTiles=[],d=new Set(Object.values(TerrainType));this.minTileHeight=Number.POSITIVE_INFINITY;for(let e=this.maxTileHeight=0,t=i.length;e<t;++e){var p=i[e],g=r.getTileImage(p.tileNum,p.subTile,s),m=g.terrainType;if(!d.has(m))throw new Error(`Tile (${p.rx}, ${p.ry}) has unknown terrain type "${m}"`);var y={...p,terrainType:m,landType:getLandType(m),onBridgeLandType:void 0,rampType:g.rampType,id:p.rx+"_"+p.ry,occluded:!1},T=y.rx,f=y.ry,v=y.dx,m=y.dy;h[e]=y,o[T+f*a.width]=y,l[v+m*n.width]=y,this.minTileHeight=Math.min(this.minTileHeight,y.z),this.maxTileHeight=Math.max(this.maxTileHeight,y.z),4!==g.height||y.terrainType!==TerrainType.Cliff&&!r.isCliffTile(y.tileNum)||c.push(y),r.isHighBridgeBoundaryTile(p.tileNum)&&u.push(y)}this.computeLandBehindCliffTiles(c),this.cutoffTileHeight=this.computeCutoffTileHeight()}computeLandBehindCliffTiles(t){if(!(this.generalRules.cliffBackImpassability<2)){let e=[[-2,-2],[-1,-1],[-1,1],[1,-1],[0,1],[1,0]];t.forEach(t=>{for(var[i,r]of e){let e=this.getByMapCoords(t.rx+i,t.ry+r);e&&e.z<t.z&&e.terrainType!==TerrainType.Cliff&&e.terrainType!==TerrainType.Rough&&0===e.rampType&&(e.landType=LandType.Rock)}})}}getTileRadarColor(e){let t=this.tileSets.getTileImage(e.tileNum,e.subTile,()=>0);return t.radarLeft.clone().multiplyScalar(.5)}getAll(){return[...this.tiles]}forEach(i){for(let e=0,t=this.tiles.length;e<t;++e)i(this.tiles[e],e)}reduce(t,e){let i=e;return this.forEach(e=>{i=t(i,e)}),i}getMinTileHeight(){return this.minTileHeight}getMaxTileHeight(){return this.maxTileHeight}getCutoffTileHeight(){return this.cutoffTileHeight}computeCutoffTileHeight(){var t=this.dSize.width-1;let i=this.dSize.height-1,r=0,s=!0;for(;s&&0<i;){for(let e=1;e<t-3;e++){var a=this.getByDisplayCoords(e,i);a&&(s=!1,a.z>r&&(r=a.z))}s&&i--}return r}getAllBridgeSetTiles(){return this.bridgeSetTiles}getAllNeighbourTiles(e){var t=e.rx,e=e.ry;return[this.getByMapCoords(t+1,e+1),this.getByMapCoords(t-1,e-1),this.getByMapCoords(t-1,e+1),this.getByMapCoords(t+1,e-1),this.getByMapCoords(t,e+1),this.getByMapCoords(t+1,e),this.getByMapCoords(t-1,e),this.getByMapCoords(t,e-1)].filter(isNotNullOrUndefined)}getNeighbourTile(e,t){var i=e.rx,r=e.ry;switch(t){case TileDirection.Bottom:return this.getByMapCoords(i+1,r+1);case TileDirection.Top:return this.getByMapCoords(i-1,r-1);case TileDirection.Left:return this.getByMapCoords(i-1,r+1);case TileDirection.Right:return this.getByMapCoords(i+1,r-1);case TileDirection.BottomLeft:return this.getByMapCoords(i,r+1);case TileDirection.BottomRight:return this.getByMapCoords(i+1,r);case TileDirection.TopLeft:return this.getByMapCoords(i-1,r);case TileDirection.TopRight:return this.getByMapCoords(i,r-1);default:throw new Error("Invalid direction")}}getByDisplayCoords(e,t){if(!(e>=this.dSize.width||t>=this.dSize.height))return this.tilesByDxy[e+t*this.dSize.width]}getByMapCoords(e,t){if(!(e>=this.rSize.width||t>=this.rSize.height))return this.tilesByRxy[e+t*this.rSize.width]}getMapSize(){return this.rSize}getDisplaySize(){return this.dSize}getInRectangle(e,t){let i,r,s,a;a=t?(i=e.rx,r=e.ry,s=t.width,t.height):(i=e.x,r=e.y,s=e.width,e.height);let n=[];for(let t=0;t<s;t++)for(let e=0;e<a;e++){var o=i+t,l=r+e,l=this.getByMapCoords(o,l);l&&n.push(l)}return n}getPlaceholderTile(e,t){var i=this.tiles[0],i=i.dx-i.rx+i.ry+1;return{rx:e,ry:t,dx:e-t+i-1,dy:e+t-i-1,z:0,id:e+"_"+t,landType:LandType.Rock,terrainType:TerrainType.Rock1,rampType:0,subTile:0,tileNum:0,occluded:!1,onBridgeLandType:void 0}}}class TiberiumTrait{static canBePlacedOn(e,t){return[LandType.Clear,LandType.Road,LandType.Rough].includes(e.landType)&&!t.getGroundObjectsOnTile(e).find(e=>!e.isSmudge()&&!e.isUnit())}constructor(e,t){this.gameObject=e,this.rules=t}getTiberiumType(){return this.rules.type}collectBail(){var e=this.getBailCount();if(e<=0)throw new Error("Attempted to collect an ore bail, but there are none left");return this.gameObject.value--,1<e?this.getTiberiumType():void 0}spawnBails(e){this.gameObject.value=Math.min(TiberiumTrait.maxBails,this.gameObject.value+e)}removeBails(e){this.gameObject.value=Math.max(-1,this.gameObject.value-e)}getBailCount(){return this.gameObject.value+1}dispose(){this.gameObject=void 0}}TiberiumTrait.maxBails=11;class AnimTerrainEffect{destroyOre(i,r,s){if(r.landType===LandType.Tiberium&&(s.art.hasObject(i,ObjectType.Animation)?s.art.getAnimation(i):void 0)?.crater){let t=s.map.getObjectsOnTile(r).find(e=>e.isOverlay()&&e.isTiberium());if(t){r=Math.ceil(TiberiumTrait.maxBails/2),r=i.startsWith("S_CLSN")?r:s.generateRandomInt(1,r);let e=t.traits.get(TiberiumTrait);e.removeBails(r),e.getBailCount()||s.unspawnObject(t)}}}spawnSmudges(e,s,a){if(s.landType===LandType.Clear&&0===s.rampType&&a.map.mapBounds.isWithinBounds(s)&&!a.map.getObjectsOnTile(s).find(e=>!e.isUnit())){e=a.art.hasObject(e,ObjectType.Animation)?a.art.getAnimation(e):void 0;if(e?.crater){let t=e?.forceBigCraters?2:1,i=e?.scorch,r=[TileDirection.Bottom,TileDirection.BottomLeft,TileDirection.BottomRight].every(e=>a.map.tiles.getNeighbourTile(s,e));e=[...a.rules.smudgeRules.values()].filter(e=>(e.crater&&e.width===t&&e.height===t||i&&e.burn)&&!((1<e.width||1<e.height)&&!r));e.length&&(e=e[a.generateRandomInt(0,e.length-1)].name,e=a.createObject(ObjectType.Smudge,e),a.spawnObject(e,s))}}}}class ObjectAttackedEvent{constructor(e,t,i){this.target=e,this.attacker=t,this.incidental=i,this.type=EventType.ObjectAttacked}}!function(e){e[e.None=0]="None",e[e.Shrapnel=1]="Shrapnel",e[e.LightningStrike=2]="LightningStrike",e[e.TntCharge=3]="TntCharge"}(SpecialWarheadType=SpecialWarheadType||{});const ROCKING_MAX_DMG=300;class Warhead{constructor(e){this.rules=e}canDamage(e,t,i){return!(!e.isSpawned||e.isDisposed||e.isDestroyed||e.isCrashing)&&(!(e.isTechno()&&e.warpedOutTrait.isInvulnerable()&&!this.rules.temporal)&&((!e.isUnit()||!e.moveTrait.reservedPathNodes.find(e=>e.tile===t))&&(!!e.healthTrait&&((!e.isUnit()||e.zone!==ZoneType.Air||i===ZoneType.Air)&&(!(!e.isUnit()&&i===ZoneType.Air)&&((!e.isBuilding()||!e.rules.invisibleInGame)&&(!((e.isTechno()||e.isTerrain())&&e.rules.immune&&!this.rules.temporal)&&(!(e.isTechno()&&!e.rules.warpable&&this.rules.temporal)&&(!(this.rules.radiation&&(!e.isUnit()||e.rules.immuneToRadiation))&&(!(this.rules.psychicDamage&&(!e.isUnit()||e.rules.immuneToPsionics))&&(!e.isOverlay()||!BridgeOverlayTypes.isLowBridgeHead(e.overlayId))))))))))))}computeDamage(e,t,i,r=!1){let s=e;if(0<e&&t.isTechno()&&t.invulnerableTrait.isActive())return 0;if(t.isAircraft()&&t.missileSpawnTrait&&t.zone!==ZoneType.Air)return 0;if(!i.gameOpts.destroyableBridges&&t.isOverlay()&&t.bridgeTrait)return 0;if(this.rules.radiation||this.rules.temporal||!t.isInfantry()||t.stance!==StanceType.Prone||(s*=this.rules.proneDamage),t.isTechno()||t.isOverlay()||t.isTerrain()){let e=t.isTerrain()?ArmorType.Wood:t.rules.armor;t.isOverlay()&&t.isBridge()&&((i=BridgeOverlayTypes.getOverlayBridgeType(t.overlayId))===OverlayBridgeType.Wood?e=ArmorType.Wood:i===OverlayBridgeType.Concrete&&(e=ArmorType.Concrete)),r&&t.isOverlay()&&(t.isBridge()||t.rules.wall)||(s*=this.rules.verses.get(e)),0<s&&t.isTechno()&&t.veteranTrait&&(s/=t.veteranTrait.getVeteranArmorMultiplier()),0<s&&t.isUnit()&&(s/=t.crateBonuses.armor)}return(t.isOverlay()||t.isBuilding())&&t.rules.wall&&(this.rules.wallAbsoluteDestroyer?s=Number.POSITIVE_INFINITY:this.rules.wall||this.rules.wood&&t.rules.armor===ArmorType.Wood||(s=0)),t.isOverlay()&&t.isBridge()&&(this.rules.wall||(s=0)),s=0<s?Math.floor(s):Math.ceil(s),s}inflictDamage(e,t,i,r,s=!1){let a=t.healthTrait;return e===Number.POSITIVE_INFINITY&&(e=a.getHitPoints()),a.inflictDamage(e,i,r),r.traits.filter(NotifyAttack_NotifyAttack).forEach(e=>{e[NotifyAttack_NotifyAttack.onAttack](t,i?.obj,r)}),t.onAttack(r,i),r.events.dispatch(new ObjectAttackedEvent(t,i,s)),t.isTechno()&&!this.rules.temporal&&this.supressOrScatterTarget(t,r),!a.health&&(t.isInfantry()&&(t.infDeathType=this.rules.infDeath),this.rules.temporal&&(t.deathType=DeathType.Temporal),t.isUnit()&&t.crashableTrait&&t.zone===ZoneType.Air&&!this.rules.temporal?t.crashableTrait.crash(i):r.destroyObject(t,i,void 0,s),!0)}supressOrScatterTarget(e,t){e.rules.fraidycat||e.isVehicle()&&!e.owner.isCombatant()&&e.rules.insignificant?e.unitOrderTrait.hasTasks()||(e.isInfantry()&&(e.isPanicked=!0),e.unitOrderTrait.addTask(new ScatterTask(t)),e.isInfantry()&&e.unitOrderTrait.addTask(new CallbackTask(()=>e.isPanicked=!1).setCancellable(!1))):e.isInfantry()&&(e.moveTrait.isIdle()||e.suppressionTrait?.isSuppressed())&&e.suppressionTrait?.suppress()}createDummyWeaponInfo(){return{minRange:0,range:0,speed:Number.POSITIVE_INFINITY,type:WeaponType.Primary,rules:new WeaponRules(new IniSection("Dummy")),projectileRules:new ProjectileRules(ObjectType.Projectile,new IniSection("Dummy")),warhead:this}}detonate(r,e,t,i,s,a,n,o,l,h=SpecialWarheadType.None,c,u,d=!1){var p,g,m,y,T,f=l?.weapon??this.createDummyWeaponInfo(),v=l?.obj,b=l?.player,w=h===SpecialWarheadType.Shrapnel,S=h===SpecialWarheadType.LightningStrike,A=u?u/Coords.LEPTONS_PER_TILE:this.rules.cellSpread,_=this.rules.percentAtMax;let O=new Set,E=new Map,C=new RangeHelper(r.map.tileOccupation),k=new RadialTileFinder(r.map.tiles,r.map.mapBounds,t,{width:1,height:1},0,Math.ceil(A),()=>!0);for(;p=k.getNextTile();)for(g of r.map.getObjectsOnTile(p))if((!O.has(g)||g.isBuilding())&&(n!==CollisionType.UnderBridge||!g.isUnit()||!g.onBridge)&&!(v&&g.isTechno()&&g.rules.typeImmune&&g.owner===b&&g.name===v.name)&&(g!==v||v.rules.damageSelf)&&this.canDamage(g,p,a)&&(!g.isOverlay()||!(!n&&.1<Math.abs(g.tileElevation-i)||n===CollisionType.OnBridge&&!g.isBridge()))){let e=g.isBuilding()?p===t?0:C.distance3(p,s)/Coords.LEPTONS_PER_TILE:g.isTerrain()||g.isOverlay()?C.distance3(p,t)/Coords.LEPTONS_PER_TILE:C.distance3(g,s)/Coords.LEPTONS_PER_TILE;if(A&&g.isAircraft()&&g.zone===ZoneType.Air&&(e/=2),e<.001&&(e=0),!(w&&g.isInfantry()&&b)||g.owner!==b&&!r.alliances.areAllied(g.owner,b)){if(!A)if(g.isTerrain()){if(p!==t||!this.rules.wall)continue}else if(!w&&(p!==t||!g.isBuilding()&&g!==(o.obj||o.getBridge())))continue;A&&e>A||(O.add(g),E.set(g,g.isBuilding()?(E.get(g)||[]).concat(e):[e]))}}let P=!1,I;for(m of O)if(!m.isDestroyed&&!m.isCrashing){let i=this.computeDamage(e,m,r,S);if(0<e&&!this.rules.affectsAllies&&m.isTechno()&&b&&(r.alliances.areAllied(m.owner,b)||m.owner===b)&&(i=0),i)for(var B of E.get(m)){let t=i;if(0<A&&Number.isFinite(t)&&(t=lerp(t,_*t,B/A)),Math.abs(t)<1&&(!A||.25<=t/i)&&(t=+Math.sign(t)),t=0<t?Math.floor(t):Math.ceil(t),t){let e=m.healthTrait;if(t<0){if(!v)throw new Error("Expected healer object to be set");if(e.healBy(-t,v,r),100===e.health)break}else{if(m===o.obj&&B<1&&(I=m),this.rules.causesDelayKill&&m.isBuilding()&&m.delayedKillTrait&&(y=m.healthTrait.getHitPoints(),t>=y&&(t=y-1,m.delayedKillTrait.isActive()||(y=this.rules.delayKillAtMax,T=lerp(T=this.rules.delayKillFrames,y*T,B/A),m.delayedKillTrait.activate(T,l)))),this.inflictDamage(t,m,l,r,!I))break;m.isVehicle()&&this.rules.rocker&&(0<(B=clamp(i/ROCKING_MAX_DMG,0,1))&&(T=FacingUtil.fromMapCoords(m.position.getMapPosition().clone().sub(Coords.vecWorldToGround(s)))-m.direction,m.applyRocking(T,B)))}}}else m.isTechno()&&m.invulnerableTrait.isActive()&&(P=!0)}f=f.rules.radLevel;f&&A&&r.mapRadiationTrait.createRadSite(t,f,A+1);d=d?void 0:P?r.rules.audioVisual.weaponNullifyAnim:this.pickExplodeAnim(e,I,a,r,S);if(!P&&a===ZoneType.Ground){let e=new AnimTerrainEffect;d&&e.destroyOre(d,t,r),c&&e.spawnSmudges(c,t,r),d&&e.spawnSmudges(d,t,r)}r.events.dispatch(new WarheadDetonateEvent(this,s,d,S))}pickExplodeAnim(t,i,r,s,a){if(t){if(a)return s.rules.audioVisual.weatherConBoltExplosion;if(this.rules.conventional&&r===ZoneType.Water&&(!i||i.isBuilding()||i.isVehicle()&&i.submergibleTrait)){var n=s.rules.combatDamage.splashList;return n[clamp(Math.floor(t/50),0,n.length-1)]}n=this.rules.animList.length;let e;return n?(e=s.rules.combatDamage.c4Warhead===this.rules.name?n-1:this.rules.emEffect?s.generateRandomInt(0,n-1):clamp(Math.floor(t/25),0,n-1),this.rules.animList[e]):void 0}}}Warhead.SPECIAL_WARHEAD_NAME="Special",Warhead.HE_WARHEAD_NAME="HE";class FlhCoords{constructor(e){this.forward=0,this.lateral=0,this.vertical=0,e&&3===e.length&&this.fromArray(e)}fromArray(e){return this.forward=e[0],this.lateral=e[1],this.vertical=e[2],this}clone(){return new FlhCoords([this.forward,this.lateral,this.vertical])}}class WeaponFireEvent{constructor(e,t){this.weapon=e,this.gameObject=t,this.type=EventType.WeaponFire}}class WeaponTargeting{constructor(e,t,i,r,s,a){this.weaponType=e,this.projectileRules=t,this.weaponRules=i,this.warheadRules=r,this.gameObject=s,this.generalRules=a,this.targetChecks=[],this.initConditions()}initConditions(){this.projectileRules.isAntiGround||this.targetChecks.push(e=>!!e);const a=this.generalRules.prism.type;this.gameObject.name===a&&this.weaponType===WeaponType.Secondary?this.targetChecks.push((e,t,i,r,s)=>!(!s||!e?.isBuilding()||e.name!==a||e.owner!==this.gameObject.owner)):this.warheadRules.electricAssault?this.targetChecks.push((e,t,i,r,s)=>!(!r&&!s||!e?.isBuilding()||!e.overpoweredTrait||e.owner!==this.gameObject.owner)):this.weaponRules.damage<0?this.targetChecks.push((e,t,i)=>!!(e!==this.gameObject&&e?.isUnit()&&i.areFriendly(e,this.gameObject)&&e.healthTrait.health<100&&this.gameObject.isAircraft()===e.isAircraft())):(this.gameObject.rules.attackCursorOnFriendlies||this.warheadRules.bombDisarm?this.targetChecks.push((e,t,i,r,s)=>!s&&!!(!this.warheadRules.bombDisarm||e?.isTechno()&&e.tntChargeTrait?.hasCharge())):this.targetChecks.push((e,t,i,r)=>!((!r||this.warheadRules.mindControl)&&e?.isTechno()&&i.areFriendly(e,this.gameObject))),this.targetChecks.push((e,t,i)=>!(e?.isTechno()&&e.cloakableTrait?.isCloaked()&&!i.alliances.haveSharedIntel(this.gameObject.owner,e.owner))),this.weaponRules.limboLaunch&&this.targetChecks.push((e,t,i,r,s)=>!(s&&e&&(e.isVehicle()||e.isAircraft())&&e.parasiteableTrait?.isInfested())),this.warheadRules.ivanBomb&&this.targetChecks.push(e=>!(!e?.isTechno()||!e.tntChargeTrait||e.tntChargeTrait.hasCharge())),this.warheadRules.parasite&&this.targetChecks.push((e,t,i,r)=>!!(!e&&r||e?.isInfantry()||(e?.isVehicle()||e?.isAircraft())&&e.parasiteableTrait)),this.warheadRules.mindControl&&this.targetChecks.push(e=>!(!e?.isTechno()||!e.mindControllableTrait)),this.warheadRules.temporal||this.targetChecks.push((e,t,i,r,s)=>!(s&&e?.isTechno()&&e.warpedOutTrait.isInvulnerable())),this.gameObject.rules.natural&&this.targetChecks.push(e=>!e?.isTechno()||!e.rules.unnatural)),this.targetChecks.push((e,t)=>this.canTargetZone(e,t))}canTarget(t,i,r,s,a){return this.targetChecks.every(e=>e(t,i,r,s,a))}canTargetZone(e,t){let i;if(e?.isUnit()){if(e?.isInfantry()&&e.stance===StanceType.Paradrop&&2<e.tileElevation)return this.projectileRules.isAntiAir&&(this.projectileRules.isAntiGround||this.weaponType===WeaponType.Secondary);if(e.zone===ZoneType.Air)return this.projectileRules.isAntiAir;if(this.weaponType===WeaponType.Secondary&&this.projectileRules.isAntiAir&&!this.projectileRules.isAntiGround)return!1;i=e.zone}else i=t.landType===LandType.Water?ZoneType.Water:ZoneType.Ground;return i===ZoneType.Water?this.canTargetNaval(this.gameObject.rules.navalTargeting,this.gameObject,e,this.weaponType):this.canTargetLand(this.gameObject.rules.landTargeting,this.weaponType)}canTargetLand(e,t){switch(e){case LandTargeting.LandOk:return!0;case LandTargeting.LandNotOk:return!1;case LandTargeting.LandSecondary:return t===WeaponType.Secondary;default:throw new Error(`Unhandled LandTargeting value "${e}"`)}}canTargetNaval(e,t,i,r){switch(e){case NavalTargeting.UnderwaterNever:return!i||!(i.isVehicle()&&i.submergibleTrait?.isSubmerged());case NavalTargeting.UnderwaterSecondary:return i&&i.isVehicle()&&i.submergibleTrait&&!t.rules.spawned?r===WeaponType.Secondary:r===WeaponType.Primary;case NavalTargeting.UnderwaterOnly:return!!(i&&i.isVehicle()&&i.submergibleTrait);case NavalTargeting.OrganicSecondary:return i?.isTechno()&&i.rules.organic?r===WeaponType.Secondary:r===WeaponType.Primary;case NavalTargeting.SealSpecial:return i?.isTechno()&&i.rules.naval&&!i.rules.organic&&(i.isBuilding()||i.rules.speedType===SpeedType.Float)?r===WeaponType.Secondary:r===WeaponType.Primary;case NavalTargeting.NavalAll:return!0;case NavalTargeting.NavalNone:return!1;default:throw new Error(`Unhandled NavalTargeting value "${e}"`)}}}const ARCING_PROJECTILE_SPEED=50,BOMBER_BURST=5,NON_FIGHTER_BURST=2,FIGHTER_BURST=1;class Weapon{static factory(e,t,i,r,s){var a=r.getWeapon(e);let n=a.warhead;n===Warhead.SPECIAL_WARHEAD_NAME&&(n=Weapon.findSpecialWarheadName(a,i,r));var o=new Warhead(r.getWarhead(n)),e=r.getProjectile(a.projectile),r=new WeaponTargeting(t,e,a,o.rules,i,r.general);return new this(t,i,a,o,e,s||new FlhCoords,r)}static findSpecialWarheadName(e,t,i){let r;if(!e.spawner)throw new Error(`Weapon "${e.name} can't use "Special" warhead without Spawner=yes`);if(t.rules.spawns===i.general.v3Rocket.type)r=i.combatDamage.v3Warhead;else if(t.rules.spawns===i.general.dMisl.type)r=i.combatDamage.dMislWarhead;else{if(!t.rules.spawns)throw new Error(`Can't use "Special" warhead on unit type "${t.name}" without "Spawns"`);t=i.getObject(t.rules.spawns,ObjectType.Aircraft);if(!t.primary)throw new Error(`Spawned unit "${t.name}" doesn't have a primary weapon`);r=i.getWeapon(t.primary).warhead}return r}static computeSpeed(e,t){return t.arcing?.75*ObjectRules.iniSpeedToLeptonsPerTick(ARCING_PROJECTILE_SPEED,100):!t.rot||t.inviso||e.isLaser||e.isElectricBolt?Number.POSITIVE_INFINITY:e.speed}constructor(e,t,i,r,s,a,n){this.type=e,this.gameObject=t,this.rules=i,this.warhead=r,this.projectileRules=s,this.flh=a,this.targeting=n,this.cooldownTicks=0,this.burstsLeft=0,this.burstIndex=0,this.useBurstDelay=!1,this.lateralMuzzleMult=1,this.distributedFireAngle=t.rules.distributedFire&&t.rules.radialFireSegments?-90:0}get name(){return this.rules.name}get minRange(){return this.rules.minimumRange}get range(){return this.gameObject.isBuilding()&&!this.gameObject.overpoweredTrait&&this.type===WeaponType.Secondary&&this.gameObject.primaryWeapon?Math.min(this.gameObject.primaryWeapon.rules.range,this.rules.range):this.rules.range}get speed(){return Weapon.computeSpeed(this.rules,this.projectileRules)}get rof(){let e=this.rules.rof;return this.gameObject.isBuilding()&&this.gameObject.garrisonTrait?.isOccupied()&&(e/=this.gameObject.garrisonTrait.units.length),this.gameObject.veteranTrait&&(e*=this.gameObject.veteranTrait.getVeteranRofMultiplier()),Math.floor(e)}getCooldownTicks(){return this.cooldownTicks}expireCooldown(){this.cooldownTicks=0}resetCooldown(){this.cooldownTicks=this.rof}hasBurstsLeft(){return 0<this.burstsLeft}resetBursts(){this.burstsLeft=0,this.burstIndex=0,this.resetCooldown(),this.gameObject.ammoTrait&&0<this.gameObject.ammoTrait.ammo&&this.gameObject.ammoTrait.ammo--}tick(){0<this.cooldownTicks&&this.cooldownTicks--}getBurstsFired(){return this.burstIndex}fire(s,a,n=1){let o=this.gameObject,e,t=0;if(!o.airSpawnTrait||!this.rules.spawner||(e=o.airSpawnTrait.prepareLaunch(o,s,a),t=o.airSpawnTrait.availableSpawns,e)){this.burstsLeft?(this.burstsLeft--,this.burstIndex++,this.lateralMuzzleMult*=-1):(this.useBurstDelay=!1,this.burstIndex=0,e?this.burstsLeft=t:this.gameObject.isAircraft()?this.burstsLeft=this.projectileRules.iniRot<=1?BOMBER_BURST-1:this.gameObject.rules.fighter?FIGHTER_BURST-1:NON_FIGHTER_BURST-1:(this.burstsLeft=this.rules.burst-1,this.useBurstDelay=!0),this.lateralMuzzleMult=1),0<this.burstsLeft&&(e&&0<t?this.cooldownTicks=this.rules.iniSpeed:this.gameObject.isAircraft()?this.cooldownTicks=this.rules.rof:this.cooldownTicks=this.useBurstDelay&&void 0!==this.gameObject.rules.burstDelay[this.burstIndex]?this.gameObject.rules.burstDelay[this.burstIndex]:a.generateRandomInt(3,5)),this.burstsLeft||this.resetBursts(),this.rules.limboLaunch&&(a.limboObject(this.gameObject,{selected:a.getUnitSelection().isSelected(this.gameObject),controlGroup:a.getUnitSelection().getOrCreateSelectionModel(this.gameObject).getControlGroupNumber()}),this.warhead.rules.parasite&&(s.obj?.isVehicle()||s.obj?.isAircraft())&&s.obj.parasiteableTrait&&(s.obj.parasiteableTrait.beingBoarded=!0));let i=e??a.createProjectile(this.projectileRules.name,this.gameObject,this,s,!1);i.isAircraft()||(i.baseDamageMultiplier=n*(this.gameObject.isUnit()?this.gameObject.crateBonuses.firepower:1));let r=this.flh.clone();r.lateral*=this.lateralMuzzleMult;var l=o.position.getMapPosition();if(a.map.isWithinHardBounds(l)){i.position.moveToLeptons(l),i.position.tileElevation=o.position.tileElevation;let e=new Vector2(r.lateral,r.forward);n=this.getMuzzleFacing()+this.distributedFireAngle;e=rotateVec2(e,n);var l=rotateVec2(l=new Vector2(0,o.art.turretOffset),o.direction);e.add(l),o.rules.radialFireSegments&&o.rules.distributedFire&&(l=Math.floor(180/o.rules.radialFireSegments),this.distributedFireAngle=(this.distributedFireAngle+l+90)%180-90),i.direction=n,o.isBuilding()&&o.rules.turretAnim&&(h=Coords.screenDistanceToWorld(o.rules.turretAnimX,o.rules.turretAnimY),n=o.getFoundationCenterOffset(),i.position.moveByLeptons(-n.x+h.x,-n.y+h.y));let t=new Vector3_Vector3(e.x,r.vertical,-e.y);var h=t.clone().add(i.position.worldPosition);if(a.map.isWithinHardBounds(h)&&i.position.moveByLeptons3(t),i.tileElevation<0&&(i.position.tileElevation=0),i.isAircraft()?a.unlimboObject(i,i.position.tile):a.spawnObject(i,i.position.tile),this.rules.revealOnFire&&s.obj?.isTechno()){let e=a.mapShroudTrait.getPlayerShroud(s.obj.owner);e?.isShrouded(o.tile,o.tileElevation)&&e.revealTemporarily(o)}this.rules.decloakToFire&&this.gameObject.cloakableTrait?.uncloak(a),a.events.dispatch(new WeaponFireEvent(this,this.gameObject))}else e&&(e.owner.removeOwnedObject(e),e.dispose())}}getMuzzleFacing(){let e=this.gameObject,t;return t=!e.isInfantry()&&!e.isAircraft()&&(e.isBuilding()||e.isVehicle())&&e.turretTrait?e.turretTrait.facing:e.direction,t}}Weapon.NUKE_PAYLOAD_NAME="NukePayload";class NukeEffect extends SuperWeaponEffect{constructor(e,t,i,r){super(e,t,i),this.weaponType=r}onStart(t){var i=t.rules.getWeapon(this.weaponType),r=t.createTarget(void 0,this.tile),s=this.owner.getOwnedObjectsByType(ObjectType.Building).find(e=>e.rules.nukeSilo);if(s){let e=Weapon.factory(i.name,WeaponType.Primary,s,t.rules);e.fire(r,t)}else this.fireLooseNuke(i,r,t)}fireLooseNuke(t,i,r){var s=new Vector2(this.tile.rx+.5,this.tile.ry+.5).multiplyScalar(Coords.LEPTONS_PER_TILE);if(r.map.isWithinHardBounds(s)){let e=r.createLooseProjectile(t.name,this.owner,i);e.position.moveToLeptons(s),e.position.tileElevation=Coords.worldToTileHeight(e.rules.detonationAltitude),r.spawnObject(e,e.position.tile)}}onTick(e){return!0}}class LightningStormCloudEvent{constructor(e){this.position=e,this.type=EventType.LightningStormCloud}}class LightningStormManifestEvent{constructor(e){this.target=e,this.type=EventType.LightningStormManifest}}!function(e){e[e.Approaching=0]="Approaching",e[e.Manifesting=1]="Manifesting"}(State=State||{});class LightningStormEffect extends SuperWeaponEffect{constructor(){super(...arguments),this.state=State.Approaching,this.clouds=[]}onStart(e){e=e.rules.general.lightningStorm;this.manifestStartTimer=e.deferment,this.manifestEndTimer=e.duration,this.nextDirectHitTimer=0,this.nextRandomHitTimer=0}onTick(t){if(this.state===State.Approaching&&(0<this.manifestStartTimer?this.manifestStartTimer--:(this.state=State.Manifesting,t.events.dispatch(new LightningStormManifestEvent(this.tile)))),this.state===State.Manifesting){var i,s=t.rules.general.lightningStorm;if(0<this.manifestEndTimer&&(this.manifestEndTimer--,0<this.nextDirectHitTimer&&this.nextDirectHitTimer--,this.nextDirectHitTimer<=0&&(this.nextDirectHitTimer=s.hitDelay,this.spawnCloudAt(this.tile,t)),0<this.nextRandomHitTimer&&this.nextRandomHitTimer--,this.nextRandomHitTimer<=0)){this.nextRandomHitTimer=s.scatterDelay;var a=Math.floor(s.cellSpread/2);let i=s.separation,r=new RangeHelper(t.map.tileOccupation),e=new RandomTileFinder(t.map.tiles,t.map.mapBounds,this.tile,a,t,t=>!this.clouds.some(e=>r.tileDistance(t,e.tile)<i),!1);a=e.getNextTile();a&&this.spawnCloudAt(a,t)}for(i of this.clouds.slice())if(0<i.ticksLeft){if(i.ticksLeft--,i.ticksLeft===Math.floor(i.durationTicks/2)){var r=s.warhead;let e=new Warhead(t.rules.getWarhead(r));var n=i.tile,o=t.map.tileOccupation.getBridgeOnTile(n),l=o?.tileElevation??0,r=t.map.getTileZone(n);e.detonate(t,s.damage,n,l,Coords.tile3dToWorld(n.rx+.5,n.ry+.5,n.z+l),r,o?CollisionType.OnBridge:CollisionType.None,t.createTarget(o,n),{player:this.owner,weapon:void 0},SpecialWarheadType.LightningStrike)}}else this.clouds.splice(this.clouds.indexOf(i),1);if(!this.clouds.length&&this.manifestEndTimer<=0)return!0}return!1}spawnCloudAt(e,t){var i=t.rules.audioVisual.weatherConClouds,i=t.generateRandomInt(0,i.length-1);let r=t.art.getAnimation(t.rules.audioVisual.weatherConClouds[i]);i=r.art.getNumber("Rate",60*GameSpeed.BASE_TICKS_PER_SECOND)/60,i=Math.floor(GameSpeed.BASE_TICKS_PER_SECOND/i*60);this.clouds.push({tile:e,durationTicks:i,ticksLeft:i});i=(t.map.tileOccupation.getBridgeOnTile(e)?.tileElevation??0)+Coords.worldToTileHeight(t.rules.general.flightLevel),i=Coords.tile3dToWorld(e.rx+.5,e.ry+.5,e.z+i);t.events.dispatch(new LightningStormCloudEvent(i))}}class IronCurtainEffect extends SuperWeaponEffect{onStart(e){var t,i,r=e.rules.combatDamage.ironCurtainDuration,s={player:this.owner};let a=new RadialTileFinder(e.map.tiles,e.map.mapBounds,this.tile,{width:1,height:1},0,1,()=>!0);for(;t=a.getNextTile();)for(i of e.map.getGroundObjectsOnTile(t))!i.isTechno()||i.isDestroyed||i.isUnit()&&i.tile!==t||i.rules.missileSpawn||(i.rules.organic?e.destroyObject(i,s):(i.invulnerableTrait.setActiveFor(r,e.currentTick),(i.isVehicle()||i.isAircraft())&&i.parasiteableTrait?.isInfested()&&i.parasiteableTrait.destroyParasite(s,e)))}onTick(e){return!0}}class ChronoSphereEffect extends SuperWeaponEffect{constructor(e,t,i,r){super(e,t,i),this.tile2=r,this.objectsToTeleport=[]}onStart(i){this.delayTicks=i.rules.general.chronoDelay;let r=i.map.tiles;for(let t=-1;t<=1;t++)for(let e=-1;e<=1;e++){var s=r.getByMapCoords(this.tile.rx+t,this.tile.ry+e);if(s){var a,n=!!s.onBridgeLandType,o=r.getByMapCoords(this.tile2.rx+t,this.tile2.ry+e);for(a of i.map.getGroundObjectsOnTile(s))!a.isUnit()||a.tile!==s||a.onBridge!==n||a.isInfantry()&&a.stance===StanceType.Paradrop&&2<a.tileElevation||a.isDisposed||a.invulnerableTrait.isActive()||(a.rules.organic&&!a.rules.teleporter||!o?i.destroyObject(a,{player:this.owner}):a.warpedOutTrait.isActive()||(a.warpedOutTrait.setActive(!0,!0,i),this.objectsToTeleport.push({obj:a,destTile:o})))}}}onTick(c){if(0<this.delayTicks&&this.delayTicks--,this.delayTicks)return!1;for(let{obj:l,destTile:h}of this.objectsToTeleport)if(l.isSpawned){let i=!1,r=h?c.map.tileOccupation.getBridgeOnTile(h):void 0,s=c.map.getGroundObjectsOnTile(h),a=s.find(e=>e.isBuilding());var u=s.some(e=>c.rules.general.padAircraft.includes(e.name)),t=c.rules.general.padAircraft.includes(l.name)&&!!a?.helipadTrait&&!!a.dockTrait?.getAllDockTiles().includes(h)&&!a.dockTrait.hasReservedDockAt(a.dockTrait.getDockNumberByTile(h))&&a.owner===l.owner;let e=!1,n=l.rules.speedType,o=l.isInfantry();l.rules.movementZone===MovementZone.Fly&&(n=SpeedType.Wheel);var d=c.map.mapBounds.isWithinBounds(h);if(!(t||c.map.terrain.getPassableSpeed(h,n,o,!!r)&&d)){let t=!1;if(!u&&(0<c.map.terrain.getPassableSpeed(h,n,o,!!r,void 0,!0)||!d)){a&&(i=!0);let e=new RadialTileFinder(c.map.tiles,c.map.mapBounds,h,{width:1,height:1},1,15,e=>0<c.map.terrain.getPassableSpeed(e,n,o,!!e.onBridgeLandType)&&!c.map.terrain.findObstacles({tile:e,onBridge:!!e.onBridgeLandType},l).length);d=e.getNextTile();d&&(h=d,r=c.map.tileOccupation.getBridgeOnTile(h),s=c.map.getGroundObjectsOnTile(h),t=!0)}t||(l.moveTrait.teleportUnitToTile(h,r,!0,!1,c),l.warpedOutTrait.setActive(!1,!0,c),c.map.getTileZone(h)===ZoneType.Water&&(l.deathType=DeathType.Sink),c.destroyObject(l,{player:this.owner}),e=!0)}for(let t of s)t.isDisposed||t.isUnit()&&(this.objectsToTeleport.some(({obj:e})=>e===t)||t.onBridge!==!!r&&t.tile===h||2<Math.abs(t.tileElevation-l.tileElevation)||(t.isInfantry()&&t.stance!==StanceType.Paradrop&&(t.deathType=DeathType.Crush),c.destroyObject(t,{player:this.owner,obj:l})));if(!e){if(l.moveTrait.teleportUnitToTile(h,r,!0,!1,c),t&&a?.dockTrait){t=a.dockTrait.getAllDockTiles().indexOf(h);if(a.dockTrait.undockUnitAt(t),a.dockTrait.hasReservedDockAt(t))throw new Error("Target building dock is already reserved by another unit");a.dockTrait.dockUnitAt(l,t)}i?l.warpedOutTrait.setTimed(c.rules.general.chronoDelay,!1,c):l.warpedOutTrait.setActive(!1,!0,c)}}return!0}}(NotifySuperWeaponDeactivate=NotifySuperWeaponDeactivate||{}).onDeactivate=Symbol();class SuperWeaponsTrait{constructor(){this.effects=[]}[NotifyTick.onTick](i){for(var e of i.getCombatants()){var t;for(t of e.superWeaponsTrait.getAll())t.update(i)}for(let t of this.effects)t.status===EffectStatus.NotStarted&&(t.onStart(i),t.status=EffectStatus.Running),t.onTick(i)&&(t.status=EffectStatus.Finished,i.traits.filter(NotifySuperWeaponDeactivate).forEach(e=>{e[NotifySuperWeaponDeactivate.onDeactivate](t.type,t.owner,i)}));this.effects=this.effects.filter(e=>e.status!==EffectStatus.Finished)}[NotifyPower.onPowerLow](e,t){e.superWeaponsTrait?.getAll()?.filter(e=>e.rules.isPowered).forEach(e=>{this.updateTimer(e,!1)})}[NotifyPower.onPowerRestore](e,t){e.superWeaponsTrait?.getAll()?.filter(e=>e.rules.isPowered).forEach(e=>{this.updateTimer(e,!0)})}[NotifyPower.onPowerChange](e,t){}[NotifyWarpChange.onChange](e,t){var i;e.owner.powerTrait&&e.isBuilding()&&e.superWeaponTrait&&((i=e.superWeaponTrait.getSuperWeapon(e))&&this.updateTimer(i,!e.owner.powerTrait.isLowPower()))}updateTimer(e,t){var i=this.superWeaponHasValidBuilding(e);t&&i?e.resumeTimer():e.pauseTimer()}superWeaponHasValidBuilding(t){return[...t.owner.buildings].find(e=>!(e.superWeaponTrait?.getSuperWeapon(e)!==t||e.warpedOutTrait.isActive()&&t.rules.isPowered))}addEffect(e){this.effects.push(e)}activateSuperWeapon(t,e,i,r,s){let a=e.superWeaponsTrait?.getAll().find(e=>e.rules.type===t);if(a&&a.status===SuperWeaponStatus.Ready){if(a.oneTimeOnly){e.superWeaponsTrait.remove(a.name);for(var n of e.buildings)n.rules.superWeapon===a.name&&n.superWeaponTrait&&n.superWeaponTrait.addSuperWeaponToPlayerIfNeeded(e,i)}else a.resetTimer();this.activateEffect(a.rules,e,i,r,s)}}activateEffect(e,i,r,s,a,n=!1){const o=e.type;if(void 0!==o){let t=[];switch(o){case SuperWeaponType.AmerParaDrop:for(var[l,h]of r.rules.general.paradrop.amerParaDrop.entries())r.rules.hasObject(h.inf,ObjectType.Infantry)?t.push(new ParadropEffect(o,i,s,h,l)):console.warn(`Can't paradrop unknown infantry type "${h.inf}"`);break;case SuperWeaponType.ParaDrop:{let e=r.rules.general.paradrop.getParadropSquads(i.country.side);for(var[c,u]of e.entries())r.rules.hasObject(u.inf,ObjectType.Infantry)?t.push(new ParadropEffect(o,i,s,u,c)):console.warn(`Can't paradrop unknown infantry type "${u.inf}"`);break}case SuperWeaponType.MultiMissile:if(!e.weaponType)throw new Error("Missing WeaponType in super weapon rules");t.push(new NukeEffect(o,i,s,e.weaponType));break;case SuperWeaponType.LightningStorm:t.push(new LightningStormEffect(o,i,s));break;case SuperWeaponType.IronCurtain:t.push(new IronCurtainEffect(o,i,s));break;case SuperWeaponType.ChronoSphere:if(!a)throw new Error("Missing tile2 action param");t.push(new ChronoSphereEffect(o,i,s,a))}for(var d of t)this.addEffect(d);r.traits.filter(NotifySuperWeaponActivate).forEach(e=>{e[NotifySuperWeaponActivate.onActivate](o,i,r,s,a)}),r.events.dispatch(new SuperWeaponActivateEvent(o,i,s,a,n))}}}class ObjectCloakChangeEvent{constructor(e){this.target=e,this.type=EventType.ObjectCloakChange}}(NotifyDamage=NotifyDamage||{}).onDamage=Symbol();class CloakableTrait{constructor(e,t){this.gameObject=e,this.cloakDelayMinutes=t,this.isActive=!1,this.resetCloakCooldown()}isCloaked(){return this.isActive}uncloak(e){var t=this.isActive;this.resetCloakCooldown(),t&&(this.isActive=!1,e.events.dispatch(new ObjectCloakChangeEvent(this.gameObject)))}resetCloakCooldown(){this.cooldownTicks=Math.floor(60*this.cloakDelayMinutes*GameSpeed.BASE_TICKS_PER_SECOND)}[NotifySpawn.onSpawn](e,t){this.resetCloakCooldown()}[NotifyTick_NotifyTick.onTick](e,t){0<this.cooldownTicks&&this.cooldownTicks--,!(this.cooldownTicks<=0)||this.isActive||e.isVehicle()&&e.submergibleTrait&&!e.submergibleTrait.isSubmerged()||e.temporalTrait.getTarget()||(this.isActive=!0,t.events.dispatch(new ObjectCloakChangeEvent(this.gameObject)))}[NotifyDamage.onDamage](e,t){this.uncloak(t)}dispose(){this.gameObject=void 0}}!function(e){e[e.Riparius=0]="Riparius",e[e.Cruentus=1]="Cruentus",e[e.Vinifera=2]="Vinifera",e[e.Aboreus=3]="Aboreus",e[e.Ore=0]="Ore",e[e.Gems=1]="Gems",e[e.Ore2=2]="Ore2",e[e.Ore3=3]="Ore3"}(TiberiumType=TiberiumType||{});class OreOverlayTypes{static getOverlayTibType(e){return this.isRiparius(e)?TiberiumType.Riparius:this.isCruentus(e)?TiberiumType.Cruentus:this.isVinifera(e)?TiberiumType.Vinifera:this.isAboreus(e)?TiberiumType.Aboreus:void 0}static isRiparius(e){return e>=this.minIdRiparius&&e<=this.maxIdRiparius}static isCruentus(e){return e>=this.minIdCruentus&&e<=this.maxIdCruentus}static isVinifera(e){return e>=this.minIdVinifera&&e<=this.maxIdVinifera}static isAboreus(e){return e>=this.minIdAboreus&&e<=this.maxIdAboreus}}OreOverlayTypes.minIdRiparius=102,OreOverlayTypes.maxIdRiparius=127,OreOverlayTypes.minIdCruentus=27,OreOverlayTypes.maxIdCruentus=38,OreOverlayTypes.minIdVinifera=127,OreOverlayTypes.maxIdVinifera=146,OreOverlayTypes.minIdAboreus=147,OreOverlayTypes.maxIdAboreus=166;class OreSpread{static calculateOverlayId(e,t){var i=t.dx,t=t.dy,i=Math.floor((t-9)/2%12*((t-8)/2%12)%12-(i-13)/2%12*((i-12)/2%12)%12+12e4);return i%=12,e===TiberiumType.Riparius?OreOverlayTypes.minIdRiparius+i:e===TiberiumType.Cruentus?OreOverlayTypes.minIdCruentus+i:e===TiberiumType.Vinifera?OreOverlayTypes.minIdVinifera+i:e===TiberiumType.Aboreus?OreOverlayTypes.minIdAboreus+i:void 0}}var SequenceType,LightingType,PowerLevel,QueueType,QueueStatus,AttackState,NotifySell,LayerType,NotifyWarpChange_NotifyWarpChange,NotifyProduceUnit,FactoryStatus,NotifyBuildStatus,RepairStatus,ShroudType,ShroudFlag,BuildStatus,NotifyOrder,OrderType,HarvesterStatus,NotifyHeal,ProjectileState,DeployFireState,NotifyHealthChange,NotifyHealthChange_NotifyHealthChange,HealthLevel,SpawnStatus,NotifyTargetDestroy,BridgeHeadType,Box2_THREE=__webpack_require__(70);class Box2 extends Box2_THREE.Box2{}const EDGE_SPAWN_CHANCE=2/3,WATER_MAP_EDGE_SPAWN_CHANCE=1/3,UNSUPPORTED_POWERUP_TYPES=[PowerupType.IonStorm,PowerupType.Gas,PowerupType.Pod,PowerupType.Squad];class CrateGeneratorTrait{constructor(e){this.randomCrateSpawn=e,this.crates=[],this.availEdgeTiles=[],this.allTiles=[]}init(n){var o=n.map.tiles.getMapSize();let l=n.map.tiles,e=[],h=0;for(let a=0;a<o.width;++a){let t,i,r=!1,s=!1;for(let e=0;e<o.height;++e){var c=l.getByMapCoords(a,e);if(c&&this.canPlaceCrateOnTile(n,c)){var u=n.map.getTileZone(c)===ZoneType.Water;t?(u||(i=c),s=u):u?r=s=!0:t=i=c}else if(t&&!c)break}t&&(e.push(t),i&&i!==t&&e.push(i),r||s||h++)}this.availEdgeTiles=e,this.allTiles=l.getAll(),this.mapEdgeIsWater=0===h,this.minCrates=n.rules.crateRules.crateMinimum*n.gameOpts.humanPlayers.filter(e=>e.countryId!==OBS_COUNTRY_ID).length}[NotifyTick.onTick](t){for(var e of this.crates)e.ticksLeft--,e.ticksLeft<=0&&(t.unspawnObject(e.obj),e.obj.dispose());if(this.crates=this.crates.filter(e=>0<e.ticksLeft),this.randomCrateSpawn)for(let e=0;e<this.minCrates-this.crates.length&&this.spawnCrateAtRandom(this.allTiles,t);e++);}spawnCrateAtRandom(e,t){e=this.chooseSpawnTile(e,t);if(e)return this.spawnRandomCrateAt(e,t)}spawnRandomCrateAt(e,t){if(this.canPlaceCrateOnTile(t,e)){var i=t.map.getTileZone(e,!0)===ZoneType.Water,i=this.choosePowerup(i,t.rules.powerups.powerups,t);if(i)return this.spawnCrateAt(e,i,t)}}spawnCrateAt(t,i,r){if(this.canPlaceCrateOnTile(r,t)){var s=r.map.getTileZone(t,!0)===ZoneType.Water,a=r.rules.crateRules,s=s?a.waterCrateImg:a.crateImg;let e=r.createObject(ObjectType.Overlay,s);e.overlayId=r.rules.getOverlayId(s),e.value=0,r.spawnObject(e,t);r=60*a.crateRegen*GameSpeed.BASE_TICKS_PER_SECOND*(.5+1.5*r.generateRandom());return this.crates.push({obj:e,powerup:i,ticksLeft:r}),e}}chooseSpawnTile(e,t){return t.generateRandom()<(this.mapEdgeIsWater?WATER_MAP_EDGE_SPAWN_CHANCE:EDGE_SPAWN_CHANCE)&&this.availEdgeTiles.length&&(e=this.availEdgeTiles),this.chooseRandomTile(e,t)}chooseRandomTile(e,t){let i;let r=0;for(;i=e[t.generateRandomInt(0,e.length-1)],r++,r<100&&!this.canPlaceCrateOnTile(t,i););if(100<=r){var s=t.map.tileOccupation.getEmptyTiles();if(!s.length)return;i=s[t.generateRandomInt(0,s.length-1)]}return i}canPlaceCrateOnTile(e,t){return e.map.mapBounds.isWithinBounds(t)&&!e.map.getGroundObjectsOnTile(t).length&&0<e.map.terrain.getPassableSpeed(t,SpeedType.Amphibious,!1,!1)&&t.terrainType!==TerrainType.Shore&&0===t.rampType}choosePowerup(t,i,r){if((i=t?i.filter(e=>e.waterAllowed):i).length){var s,t=i.reduce((e,t)=>e+t.probShares,0),a=r.generateRandomInt(0,t);let e=0;for(s of i)if(e+=s.probShares,a<e)return s}}peekInsideCrate(t){return this.crates.find(e=>e.obj===t)?.powerup.type}pickupCrate(e,t,i){let r=this.crates.find(e=>e.obj===t);if(r){this.crates.splice(this.crates.indexOf(r),1),i.unspawnObject(r.obj),r.obj.dispose();let t=this.grantPowerup(e,r.powerup,r.obj.tile,i);var s;return void 0!==t&&(e.owner.cratesPickedUp++,s=i.rules.powerups.powerups.find(e=>e.type===t),i.events.dispatch(new CratePickupEvent(s,e.owner,e,r.obj.tile))),this.randomCrateSpawn&&this.spawnCrateAtRandom(this.allTiles,i),t}}grantPowerup(t,i,r,s){let a=t.owner,n=!1;if(a.isCombatant()){if(i.type===PowerupType.Unit){let e;if(![...a.buildings].some(e=>e.rules.constructionYard)&&s.rules.crateRules.freeMCV){let t=s.rules.general.baseUnit;if(!a.getOwnedObjects(!0).some(e=>t.includes(e.name))&&a.credits>=[...s.rules.ai.buildPower,...s.rules.ai.buildRefinery].map(e=>s.rules.getBuilding(e)).filter(e=>e.aiBasePlanningSide===a.country.side).reduce((e,t)=>e+t.cost,0)){var o=t.find(e=>{let t=s.rules.getObject(e,ObjectType.Vehicle);return t.isAvailableTo(a.country)&&t.hasOwner(a.country)});if(!o)throw new Error("No suitable MCV found for player country "+a.country?.name);e=s.rules.getObject(o,ObjectType.Vehicle)}}if(e||(o=(o=s.rules.crateRules.unitCrateType)?s.rules.hasObject(o,ObjectType.Vehicle)?[s.rules.getObject(o,ObjectType.Vehicle)]:[]:[...s.rules.vehicleRules.values()].filter(e=>e.crateGoodie&&0<s.map.terrain.getPassableSpeed(r,e.speedType,!1,!1))).length&&(e=o[s.generateRandomInt(0,o.length-1)]),e){let t=s.createUnitForPlayer(e,a);var l=new RadialTileFinder(s.map.tiles,s.map.mapBounds,r,{width:1,height:1},0,3,e=>0<s.map.terrain.getPassableSpeed(e,t.rules.speedType,t.isInfantry(),!1)&&!s.map.terrain.findObstacles({tile:e,onBridge:void 0},t).length).getNextTile();l?(s.spawnObject(t,l),n=!0):(a.removeOwnedObject(t),t.dispose())}}else if(i.type===PowerupType.Money){if(!i.data)throw new Error("Money powerup missing data field");l=Math.floor(Number(i.data)*(.55+2*s.generateRandom()*.45));a.credits=Math.max(0,a.credits+l),0<l&&(a.creditsGained+=l),n=!0}else if(i.type===PowerupType.HealBase){var e;for(e of a.getOwnedObjects(!0))e.isDestroyed||e.healthTrait.healToFull(void 0,s);n=!0}else if(i.type===PowerupType.Reveal)s.mapShroudTrait.revealMap(a,s),n=!0;else if(i.type===PowerupType.Darkness)s.mapShroudTrait.resetShroud(a,s),n=!0;else if(i.type===PowerupType.Veteran){if(t.veteranTrait&&!t.veteranTrait.isMaxLevel()){n=!0;var h,c=Number(i.data);for(h of this.getUnitsInCrateRadius(s,r,a))h.veteranTrait?.promote(c,s)}}else if(i.type===PowerupType.Armor){if(1===t.crateBonuses.armor){n=!0;var u,d=Number(i.data);for(u of this.getUnitsInCrateRadius(s,r,a))1===u.crateBonuses.armor&&(u.crateBonuses.armor=d)}}else if(i.type===PowerupType.Firepower){if(1===t.crateBonuses.firepower){n=!0;var p,g=Number(i.data);for(p of this.getUnitsInCrateRadius(s,r,a))1===p.crateBonuses.firepower&&(p.crateBonuses.firepower=g)}}else if(i.type===PowerupType.Speed){if(1===t.crateBonuses.speed){n=!0;var m,y=Number(i.data);for(m of this.getUnitsInCrateRadius(s,r,a))1===m.crateBonuses.speed&&(m.crateBonuses.speed=y)}}else if(i.type===PowerupType.Cloak){if(!t.cloakableTrait){n=!0;for(var T of this.getUnitsInCrateRadius(s,r,a))T.cloakableTrait||(T.cloakableTrait=new CloakableTrait(T,s.rules.general.cloakDelay),s.addObjectTrait(T,T.cloakableTrait))}}else if(i.type===PowerupType.ICBM){var f=[...s.rules.superWeaponRules.values()].find(e=>e.type===SuperWeaponType.MultiMissile);if(f&&a.superWeaponsTrait&&!a.superWeaponsTrait.has(f.name)){let e=s.createSuperWeapon(f.name,a,!0);e.isGift=!0,a.superWeaponsTrait.add(e),n=!0}}else if(i.type===PowerupType.Invulnerability){var v=[...s.rules.superWeaponRules.values()].find(e=>e.type===SuperWeaponType.IronCurtain);v&&(s.traits.get(SuperWeaponsTrait).activateEffect(v,a,s,r,void 0,!0),n=!0)}else if(i.type===PowerupType.Explosion||i.type===PowerupType.Napalm){n=!0;f=Number(i.data),v=i.type===PowerupType.Napalm?s.rules.combatDamage.flameDamage:s.rules.combatDamage.c4Warhead;let e=new Warhead(s.rules.getWarhead(v));e.detonate(s,f,t.tile,t.tileElevation,t.position.worldPosition,t.zone,CollisionType.None,s.createTarget(t,t.tile),{player:t.owner,weapon:void 0},SpecialWarheadType.None,void 0,0)}else{if(i.type!==PowerupType.Tiberium)return void console.warn(`Unhandled powerup type "${PowerupType[i.type]}"`);{let e=new RandomTileFinder(s.map.tiles,s.map.mapBounds,r,2,s,e=>TiberiumTrait.canBePlacedOn(e,s.map)),t,i=0;for(;i++<6&&(t=e.getNextTile());){var b=OreSpread.calculateOverlayId(TiberiumType.Ore,t);if(void 0===b)throw new Error("Expected an overlayId");let e=s.createObject(ObjectType.Overlay,s.rules.getOverlayName(b));e.overlayId=b,e.value=3,s.spawnObject(e,t),n=!0}}}if(n)return i.type;i=s.rules.powerups.powerups.find(e=>e.type===PowerupType.Money&&0<e.probShares);return i?this.grantPowerup(t,i,r,s):void 0}}getUnitsInCrateRadius(e,t,i){let r=e.rules.crateRules.crateRadius,s=new RangeHelper(e.map.tileOccupation);return e.map.technosByTile.queryRange((new Box2).setFromCenterAndSize(new Vector2(t.rx,t.ry),new Vector2(r,r))).filter(e=>e.owner===i&&e.isUnit()&&s.tileDistance(e,t)<=r)}}class PowerupsRules{constructor(){this.powerups=[]}readIni(e){for(var[s,a]of e.entries){let[e,t,i,r]=a.split(",");var n=Number(e),a=PowerupType[s];void 0!==a?UNSUPPORTED_POWERUP_TYPES.includes(a)||this.powerups.push({type:a,probShares:n,animName:"<none>"!==t.toLowerCase()?t:void 0,waterAllowed:"yes"===i,data:r}):console.warn(`Unknown powerup "${s}". Skipping.`)}return this}}const mpAllowedColors=["Gold","DarkRed","DarkBlue","DarkGreen","Orange","DarkSky","Purple","Magenta"];class Rules{constructor(e,t){this.ini=e,this.logger=t,this.buildingTypes=new Map,this.vehicleTypes=new Map,this.infantryTypes=new Map,this.aircraftTypes=new Map,this.terrainTypes=new Map,this.overlayTypes=new Map,this.overlayIdsByType=new Map,this.animationTypes=new Map,this.animationNames=new Set,this.voxelAnimTypes=new Map,this.smudgeTypes=new Map,this.warheadTypes=new Map,this.tiberiumTypes=new Map,this.superWeaponTypes=new Map,this.countryTypes=new Map,this.weaponTypes=new Map,this.allObjectRules=new Map,this.buildingRules=new Map,this.infantryRules=new Map,this.vehicleRules=new Map,this.aircraftRules=new Map,this.terrainRules=new Map,this.overlayRules=new Map,this.smudgeRules=new Map,this.voxelAnimRules=new Map,this.countryRules=new Map,this.warheadRules=new Map,this.powerups=new PowerupsRules,this.colors=new Map,this.general=new GeneralRules,this.ai=new AiRules,this.crateRules=new CrateRules,this.elevationModel=new ElevationModelRules,this.mpDialogSettings=new MpDialogSettings,this.audioVisual=new AudioVisualRules,this.combatDamage=new CombatDamageRules,this.radiation=new RadiationRules,this.landRules=new Map,this.tiberiumRules=new Map,this.superWeaponRules=new Map,this.cachedWeaponRules=new Map,this.cachedProjectileRules=new Map,this.init()}hasObject(e,t){return this.allObjectRules.get(t)?.has(e)}getObject(e,t){t=this.allObjectRules.get(t)?.get(e);if(!t)throw new Error(`Missing rules for object "${e}"`);return t}getTechnoByInternalId(e,t){let i;if(t===ObjectType.Building)i=this.buildingTypes.get(e);else if(t===ObjectType.Infantry)i=this.infantryTypes.get(e);else if(t===ObjectType.Vehicle)i=this.vehicleTypes.get(e);else{if(t!==ObjectType.Aircraft)throw new Error(`Type ${ObjectType[t]} is not a techno type`);i=this.aircraftTypes.get(e)}if(void 0===i)throw new Error(`Object type "${ObjectType[t]}" with ID "${e}" not found`);return this.getObject(i,t)}getBuilding(e){var t=this.buildingRules.get(e);if(!t)throw new Error(`Missing rules for building "${e}"`);return t}getWeapon(e){let t=this.cachedWeaponRules.get(e);if(!t){var i=this.ini.getSection(e);if(!i)throw new Error(`Weapon ${e} is missing ini section`);t=new WeaponRules(i),this.cachedWeaponRules.set(e,t)}return t}getWeaponByInternalId(e){var t=this.weaponTypes.get(e);if(!t)throw new RangeError(`Weapon with internal ID "${e}" not found`);return this.getWeapon(t)}getWarhead(t){let i=t.toLowerCase(),r=this.warheadRules.get(i);if(!r){let e=this.ini.getSection(t);if(!e&&(e=this.ini.getOrderedSections().find(e=>e.name.toLowerCase()===i),!e))throw new Error("Unknown warhead "+t);r=new WarheadRules(e),this.warheadRules.set(i,r)}return r}getProjectile(t){let i=t.toLowerCase(),r=this.cachedProjectileRules.get(i);if(!r){let e=this.ini.getSection(t);if(!e&&(e=this.ini.getOrderedSections().find(e=>e.name.toLowerCase()===i),!e))throw new Error(`Projectile ${t} is missing ini section`);r=new ProjectileRules(ObjectType.Projectile,e),this.cachedProjectileRules.set(i,r)}return r}getOverlayName(e){var t=this.overlayTypes.get(e);if(!t)throw new Error("Invalid overlay id "+e);return t}hasOverlayId(e){return this.overlayTypes.has(e)}getOverlayId(e){var t=this.overlayIdsByType.get(e);if(void 0===t)throw new Error("Invalid overlay name "+e);return t}getOverlay(e){var t=this.overlayRules.get(e);if(!t)throw new Error(`Missing rules for overlay "${e}"`);return t}getAnimationName(e){return this.animationTypes.get(e)}getCountry(e){if(!this.countryRules.has(e))throw new Error("Unknown country "+e);return this.countryRules.get(e)}getMultiplayerCountries(){return[...this.countryRules.values()].filter(e=>e.multiplay)}getMultiplayerColors(){let t=new Map;return mpAllowedColors.forEach(e=>{if(!this.colors.has(e))throw new Error(`Multiplayer color "${e}" does not exist in the rules [Colors] section.`);t.set(e,this.colors.get(e))}),t}getLandRules(e){let t=this.landRules.get(e);var i;return t||(i=e===LandType.Cliff?"Rock":LandType[e],t=(new LandRules).readIni(this.ini.getOrCreateSection(i)),this.landRules.set(e,t)),t}getTiberium(e){var t=this.tiberiumTypes.get(e);if(!t)throw new Error("Unknown tiberium type "+e);return this.tiberiumRules.get(t)}getSuperWeapon(e){if(!this.superWeaponRules.has(e))throw new Error(`Unknown superweapon type "${e}"`);return this.superWeaponRules.get(e)}getIni(){return this.ini}applySpecialFlags(e){e.initialVeteran&&(this.general.veteran.initialVeteran=!0)}init(){this.readAudioVisual(),this.readCombatDamage(),this.readRadiation(),this.readGeneral(),this.readAi(),this.readCrateRules(),this.readElevationModel(),this.readMpDialogSettings(),this.readObjectTypes("BuildingTypes",this.buildingTypes),this.readObjectTypes("InfantryTypes",this.infantryTypes),this.readObjectTypes("VehicleTypes",this.vehicleTypes),this.readObjectTypes("AircraftTypes",this.aircraftTypes),this.readObjectTypes("TerrainTypes",this.terrainTypes),this.readObjectTypes("SmudgeTypes",this.smudgeTypes),this.readObjectTypes("Animations",this.animationTypes),this.animationNames=new Set(this.animationTypes.values()),this.readObjectTypes("VoxelAnims",this.voxelAnimTypes),this.readObjectTypes("OverlayTypes",this.overlayTypes),this.overlayTypes.forEach((e,t)=>this.overlayIdsByType.set(e,t)),this.readColors(),this.readObjectTypes("Countries",this.countryTypes),this.readObjectTypes("Warheads",this.warheadTypes),this.readObjectTypes("Tiberiums",this.tiberiumTypes),this.readObjectTypes("SuperWeaponTypes",this.superWeaponTypes),this.allObjectRules.set(ObjectType.Building,this.buildingRules).set(ObjectType.Infantry,this.infantryRules).set(ObjectType.Vehicle,this.vehicleRules).set(ObjectType.Aircraft,this.aircraftRules).set(ObjectType.Terrain,this.terrainRules).set(ObjectType.Overlay,this.overlayRules).set(ObjectType.Smudge,this.smudgeRules).set(ObjectType.VoxelAnim,this.voxelAnimRules),this.readObjects(ObjectType.Building,this.buildingTypes,this.buildingRules),this.readObjects(ObjectType.Infantry,this.infantryTypes,this.infantryRules),this.readObjects(ObjectType.Vehicle,this.vehicleTypes,this.vehicleRules),this.readObjects(ObjectType.Aircraft,this.aircraftTypes,this.aircraftRules),this.readObjects(ObjectType.Terrain,this.terrainTypes,this.terrainRules),this.readObjects(ObjectType.Overlay,this.overlayTypes,this.overlayRules),this.readObjects(ObjectType.Smudge,this.smudgeTypes,this.smudgeRules),this.readObjects(ObjectType.VoxelAnim,this.voxelAnimTypes,this.voxelAnimRules),this.readCountries(),this.readWarheads(),this.readPowerups(),this.readTiberiums(),this.readSuperWeapons(),this.buildWeaponsList()}readAudioVisual(){var e=this.ini.getSection("AudioVisual");if(!e)throw new Error("Missing [AudioVisual] section");this.audioVisual.readIni(e)}readCombatDamage(){var e=this.ini.getSection("CombatDamage");if(!e)throw new Error("Missing [CombatDamage] section");this.combatDamage.readIni(e)}readRadiation(){var e=this.ini.getSection("Radiation");if(!e)throw new Error("Missing [Radiation] section");this.radiation.readIni(e)}readGeneral(){var e=this.ini.getSection("General");if(!e)throw new Error("Missing [General] section");this.general.readIni(e)}readAi(){var e=this.ini.getSection("AI");if(!e)throw new Error("Missing [AI] section");this.ai.readIni(e)}readCrateRules(){var e=this.ini.getSection("CrateRules");if(!e)throw new Error("Missing [CrateRules] section");this.crateRules.readIni(e)}readElevationModel(){var e=this.ini.getSection("ElevationModel");if(!e)throw new Error("Missing [ElevationModel] section");this.elevationModel.readIni(e)}readMpDialogSettings(){var e=this.ini.getSection("MultiplayerDialogSettings");if(!e)throw new Error("Missing [MultiplayerDialogSettings] section");this.mpDialogSettings.readIni(e)}readObjectTypes(i,r){let e=this.ini.getSection(i);if(!e)throw new Error(`Missing [${i}] section`);let s=0,a=new Set;e.entries.forEach((e,t)=>{"string"==typeof e?Number.isNaN(Number(t))?this.logger?.debug(`Non-numeric id "${t}" found in rules section [${i}]. Skipping.`):a.has(e)?this.logger?.debug(`Duplicate type "${e}" in rules section [${i}]. Skipping.`):(r.set(s++,e),a.add(e)):this.logger?.debug(`Non-string type found in rules section [${i}]. Skipping.`)})}readColors(){let e=this.ini.getSection("Colors");if(!e)throw new Error("Missing [Colors] section");e.entries.forEach((e,t)=>{var[i,r,e]=e.split(","),e=Color.fromHsv(parseInt(i,10),parseInt(r,10),parseInt(e,10));this.colors.set(t,e)})}readObjects(r,e,s){e.forEach((e,t)=>{var i=this.ini.getSection(e);i?(t=(new ObjectRulesFactory).create(r,i,this.general,t),s.set(e,t)):this.logger?.debug(ObjectType[r]+` type "${e}" has no rules section`)})}readCountries(){this.countryTypes.forEach((e,t)=>{var i=this.ini.getSection(e);if(!i)throw new Error("Missing ini section for country "+e);let r=new CountryRules(t);r.readIni(i),this.countryRules.set(e,r)})}readWarheads(){this.warheadTypes.forEach(e=>{var t=this.ini.getSection(e);t?(t=new WarheadRules(t),this.warheadRules.set(e.toLowerCase(),t)):this.logger?.debug(`Warhead "${e}" has no rules section`)})}readPowerups(){var e=this.ini.getSection("Powerups");if(!e)throw new Error("Missing [Powerups] section");this.powerups.readIni(e)}readTiberiums(){this.tiberiumTypes.forEach((e,t)=>{var i=this.ini.getSection(e);if(!i)throw new Error("Missing rules section for tiberium type "+e);this.tiberiumRules.set(e,new TiberiumRules(t).readIni(i))})}readSuperWeapons(){this.superWeaponTypes.forEach((e,t)=>{var i=this.ini.getSection(e);if(!i)throw new Error("Missing rules section for superweapon type "+e);this.superWeaponRules.set(e,new SuperWeaponRules(t).readIni(i))})}buildWeaponsList(){let e=new Set;e.add(this.general.dropPodWeapon);for(var t of this.superWeaponRules.values())t.weaponType&&e.add(t.weaponType);var r,i;e.add(Weapon.NUKE_PAYLOAD_NAME);for(let i of[...this.buildingRules.values(),...this.aircraftRules.values(),...this.vehicleRules.values(),...this.infantryRules.values()])for(r of[i.deathWeapon,i.primary,i.secondary,i.elitePrimary,i.eliteSecondary,i.occupyWeapon,i.eliteOccupyWeapon,...i.weaponCount?new Array(i.weaponCount).fill(0).map((e,t)=>[i.getWeaponAtIndex(t),i.getEliteWeaponAtIndex(t)]).flat():[]].filter(isNotNullOrUndefined).filter(e=>""!==e))e.add(r);let s=0;for(i of e)this.weaponTypes.set(s++,i)}}!function(e){e[e.Ready=0]="Ready",e[e.Guard=1]="Guard",e[e.Prone=2]="Prone",e[e.Walk=3]="Walk",e[e.FireUp=4]="FireUp",e[e.Down=5]="Down",e[e.Crawl=6]="Crawl",e[e.Up=7]="Up",e[e.FireProne=8]="FireProne",e[e.Idle1=9]="Idle1",e[e.Idle2=10]="Idle2",e[e.Die1=11]="Die1",e[e.Die2=12]="Die2",e[e.Hover=13]="Hover",e[e.Fly=14]="Fly",e[e.FireFly=15]="FireFly",e[e.Tumble=16]="Tumble",e[e.AirDeathStart=17]="AirDeathStart",e[e.AirDeathFalling=18]="AirDeathFalling",e[e.AirDeathFinish=19]="AirDeathFinish",e[e.Tread=20]="Tread",e[e.Swim=21]="Swim",e[e.WetAttack=22]="WetAttack",e[e.WetIdle1=23]="WetIdle1",e[e.WetIdle2=24]="WetIdle2",e[e.WetDie1=25]="WetDie1",e[e.WetDie2=26]="WetDie2",e[e.Deploy=27]="Deploy",e[e.Deployed=28]="Deployed",e[e.DeployedFire=29]="DeployedFire",e[e.DeployedIdle=30]="DeployedIdle",e[e.Undeploy=31]="Undeploy",e[e.Paradrop=32]="Paradrop",e[e.Cheer=33]="Cheer",e[e.Panic=34]="Panic"}(SequenceType=SequenceType||{});const facingByCardinal=new Map([["E",5],["S",3],["W",1],["N",7]]);class SequenceReader{readIni(e){let t=new Map;for(var[i,r]of e.entries){i=SequenceType[i];void 0!==i&&(r=r.split(","),r={type:i,startFrame:Number(r[0]),frameCount:Number(r[1]),facingMult:Number(r[2]),onlyFacing:r[3]?facingByCardinal.get(r[3]):void 0},t.set(i,r))}return t}}!function(e){e[e.None=0]="None",e[e.Global=1]="Global",e[e.Level=2]="Level",e[e.Ambient=3]="Ambient",e[e.Full=4]="Full",e[e.Default=5]="Default"}(LightingType=LightingType||{});class ObjectArt{static getDefaultPalette(e){switch(e){case ObjectType.Building:case ObjectType.Aircraft:case ObjectType.Infantry:case ObjectType.Vehicle:case ObjectType.Projectile:case ObjectType.VoxelAnim:return PaletteType.Unit;case ObjectType.Overlay:return PaletteType.Overlay;case ObjectType.Smudge:case ObjectType.Terrain:return PaletteType.Iso;default:ObjectType.Animation;return PaletteType.Anim}}static getDefaultLighting(e){switch(e){case ObjectType.Animation:return LightingType.None;case ObjectType.Aircraft:case ObjectType.Building:case ObjectType.Infantry:case ObjectType.Vehicle:return LightingType.Ambient;case ObjectType.Projectile:case ObjectType.VoxelAnim:return LightingType.Global;case ObjectType.Overlay:case ObjectType.Smudge:case ObjectType.Terrain:default:return LightingType.Full}}static getDefaultRemapability(e){switch(e){case ObjectType.Aircraft:case ObjectType.Building:case ObjectType.Infantry:case ObjectType.Vehicle:return!0;case ObjectType.Overlay:case ObjectType.Smudge:case ObjectType.Terrain:case ObjectType.Animation:case ObjectType.Projectile:case ObjectType.VoxelAnim:return!1;default:throw new Error("Unknown object type "+e)}}static getDefaultDrawOffset(e){switch(e){case ObjectType.Animation:case ObjectType.Building:case ObjectType.Vehicle:case ObjectType.Infantry:case ObjectType.Overlay:case ObjectType.Smudge:case ObjectType.Projectile:case ObjectType.VoxelAnim:return new Vector2(0,0);case ObjectType.Terrain:case ObjectType.Aircraft:return new Vector2(0,(Coords.ISO_TILE_SIZE+1)/2);default:throw new Error("Unknown object type "+e)}}static getDefaultShadow(e){switch(e){case ObjectType.Overlay:case ObjectType.Building:case ObjectType.Infantry:case ObjectType.Terrain:case ObjectType.Vehicle:case ObjectType.Aircraft:return!0;default:case ObjectType.Smudge:case ObjectType.Animation:case ObjectType.Projectile:case ObjectType.VoxelAnim:return!1}}static getDefaultHeight(e){switch(e){case ObjectType.Building:return 2;case ObjectType.Infantry:case ObjectType.Vehicle:case ObjectType.Aircraft:return 1;default:return 0}}static factory(e,t,i,r){let s=new this(e,t,r);return e===ObjectType.Infantry&&(!(r=r.getString("Sequence"))||(r=i.getSection(r))&&(s.sequences=(new SequenceReader).readIni(r))),s}constructor(e,t,i){this.sequences=new Map,this.dockingOffsets=[],this.type=e,this.rules=t,this.art=i,this.init()}init(){this.image=[ObjectType.Infantry,ObjectType.Vehicle,ObjectType.Aircraft].includes(this.type)?"":this.art.getString("Image"),this.report=this.art.getString("Report")||void 0,this.readRotors(),this.noHva=this.art.getBool("NoHVA"),this.startSound=this.art.getString("StartSound")||void 0,this.readMuzzleFlash(),this.readPaletteAndLightingTypes(),this.readRemapability(),this.readFlatness(),this.readDockingOffsets();var e=this.art.getNumberArray("QueueingCell");this.queueingCell=e.length?new Vector2(e[0],e[1]):void 0,this.demandLoad=this.art.getBool("DemandLoad");var t=this.art.getBool("UseLineTrail"),i=this.art.getNumberArray("LineTrailColor"),e=this.art.getNumber("LineTrailColorDecrement",ObjectArt.DEFAULT_LINE_TRAIL_DEC);t&&i.length?(this.useLineTrail=!0,this.lineTrailColor=i,this.lineTrailColorDecrement=e):this.useLineTrail=!1,this.crater=this.art.getBool("Crater"),this.forceBigCraters=this.art.getBool("ForceBigCraters"),this.scorch=this.art.getBool("Scorch"),this.height=this.art.getNumber("Height",ObjectArt.getDefaultHeight(this.type)),this.isVoxel=this.art.getBool("Voxel"),this.occupyHeight=this.art.getNumber("OccupyHeight",this.height),this.type===ObjectType.Building?this.canHideThings=this.art.getBool("CanHideThings",!0):this.canHideThings=!1,this.canBeHidden=this.art.getBool("CanBeHidden",!0),this.addOccupy=this.readAddRemoveOccupy("AddOccupy"),this.removeOccupy=this.readAddRemoveOccupy("RemoveOccupy"),this.rotates=this.art.getBool("Rotates"),this.toOverlay=this.art.getString("ToOverlay")||void 0}get imageName(){return(this.image||this.rules.imageName)+(this.rules.alternateArcticArt?"A":"")}get cameo(){let e=this.art.getString("Cameo")||ObjectArt.MISSING_CAMEO;return e.toLowerCase()}get altCameo(){let e=this.art.getString("AltCameo")||this.cameo;return e.toLowerCase()}get useTheaterExtension(){return this.art.getBool("Theater")}readPaletteAndLightingTypes(){this.paletteType=PaletteType.Default,this.lightingType=LightingType.Default,(this.rules instanceof OverlayRules?this.rules.noUseTileLandType:void 0)&&(this.paletteType=PaletteType.Iso,this.lightingType=LightingType.Full),this.art.getBool("TerrainPalette")||this.art.getBool("ShouldUseCellDrawer")?this.paletteType=PaletteType.Iso:this.art.getBool("AnimPalette")?(this.paletteType=PaletteType.Anim,this.lightingType=LightingType.None):this.art.getString("Palette")&&(this.paletteType=PaletteType.Custom,this.customPaletteName=this.art.getString("Palette")),this.art.getBool("AltPalette")&&(this.paletteType=PaletteType.Unit),(this.rules instanceof OverlayRules||this.rules instanceof TechnoRules)&&this.rules.wall&&(this.paletteType=PaletteType.Unit,this.lightingType=LightingType.Ambient),(this.rules instanceof TerrainRules||this.rules instanceof TechnoRules)&&this.rules.gate&&(this.paletteType=PaletteType.Unit),this.rules instanceof TerrainRules&&this.rules.spawnsTiberium&&(this.paletteType=PaletteType.Unit,this.lightingType=LightingType.None),this.rules instanceof OverlayRules&&(this.rules.isVeins&&(this.paletteType=PaletteType.Unit,this.lightingType=LightingType.None),this.rules.isVeinholeMonster&&(this.paletteType=PaletteType.Unit,this.lightingType=LightingType.None),this.rules.tiberium&&(this.lightingType=LightingType.None),this.rules.land===LandType.Railroad&&(this.paletteType=PaletteType.Iso,this.lightingType=LightingType.Full),this.rules.crate&&(this.paletteType=PaletteType.Iso,this.lightingType=LightingType.Full)),this.paletteType===PaletteType.Default&&(this.paletteType=ObjectArt.getDefaultPalette(this.type)),this.lightingType===LightingType.Default&&(this.lightingType=ObjectArt.getDefaultLighting(this.type))}readRemapability(){this.remapable=ObjectArt.getDefaultRemapability(this.type),this.art.getBool("TerrainPalette")||this.art.getBool("AnimPalette")?this.remapable=!1:this.rules instanceof ProjectileRules&&this.rules.firersPalette&&(this.remapable=!0)}readFlatness(){let e=!1;this.type===ObjectType.Building||this.type===ObjectType.Animation?e=this.art.getBool("Flat"):this.type===ObjectType.Smudge&&(e=!0),this.rules instanceof OverlayRules&&(this.rules.wall||this.rules.crate||this.rules.isARock||(e=!0)),this.flat=e}readRotors(){var i=this.art.getArray("Rotors");if(i.length){let t=[];for(let e=0;e<i.length;++e){var r=this.art.getNumberArray(`Rotor${e+1}Axis`,void 0,[0,1,0]),r=new Vector3_Vector3(-r[2],-r[0],r[1]).normalize();t.push({name:i[e],axis:r,speed:this.art.getNumber(`Rotor${e+1}Rate`)||void 0,idleSpeed:this.art.getNumber(`Rotor${e+1}IdleRate`)||void 0})}t.length&&(this.rotors=t)}}readMuzzleFlash(){let e=0,t="MuzzleFlash"+e,i=[];for(;this.art.has(t);){var[r,s]=this.art.getNumberArray(t);i.push({x:r,y:s}),e++,t="MuzzleFlash"+e}this.muzzleFlash=i.length?i:void 0}readDockingOffsets(){if(this.type===ObjectType.Building){var t=this.rules.numberOfDocks;for(let e=0;e<t;e++){var[i,r,s]=this.art.getNumberArray("DockingOffset"+e,/,\s*/,[0,0,0]);this.dockingOffsets.push(new Vector3_Vector3(i,s,r))}}}readAddRemoveOccupy(e){let t=0,i=[];for(;;){var r=this.art.getNumberArray(e+ ++t);if(!r.length)break;i.push(new Vector2(r[0],r[1]))}return i}get bibShape(){return this.art.getString("BibShape")}get foundation(){let e=this.art.getString("Foundation","1x1");var[t,i]=e.split(/x/i);return{width:parseInt(t,10),height:parseInt(i,10)}}get foundationCenter(){return new Vector2(Math.floor(this.foundation.width/2-.5),Math.floor(this.foundation.height/2-.5))}getDrawOffset(){if(this.rules instanceof TerrainRules&&this.rules.spawnsTiberium)return new Vector2(0,0);let e=ObjectArt.getDefaultDrawOffset(this.type);return this.rules instanceof OverlayRules&&this.rules.isARock&&(e.y+=(Coords.ISO_TILE_SIZE+1)/2),e}get hasShadow(){return this.art.getBool("Shadow",ObjectArt.getDefaultShadow(this.type))&&!this.rules.noShadow}get turretOffset(){return this.art.getNumber("TurretOffset")}get facings(){return this.art.getNumber("Facings",8)}get walkFrames(){return this.art.getNumber("WalkFrames")}get firingFrames(){return this.art.getNumber("FiringFrames")}get standingFrames(){return this.art.getNumber("StandingFrames",1)}get startWalkFrame(){return this.art.getNumber("StartWalkFrame",0)}get startStandFrame(){return this.art.getNumber("StartStandFrame",this.walkFrames*this.facings)}get startFiringFrame(){return this.art.getNumber("StartFiringFrame",(this.walkFrames+this.standingFrames)*this.facings)}get isFlamingGuy(){return this.art.getBool("IsFlamingGuy")}get runningFrames(){return this.art.getNumber("RunningFrames")}get crawls(){return this.art.getBool("Crawls",!0)}get primaryFireFlh(){return new FlhCoords(this.art.getNumberArray("PrimaryFireFLH"))}get elitePrimaryFireFlh(){var e=this.art.getNumberArray("ElitePrimaryFireFLH");return e.length?new FlhCoords(e):this.primaryFireFlh}get primaryFirePixelOffset(){return this.art.getNumberArray("PrimaryFirePixelOffset")}get secondaryFirePixelOffset(){return this.art.getNumberArray("SecondaryFirePixelOffset")}get secondaryFireFlh(){return new FlhCoords(this.art.getNumberArray("SecondaryFireFLH"))}get eliteSecondaryFireFlh(){var e=this.art.getNumberArray("EliteSecondaryFireFLH");return e.length?new FlhCoords(e):this.secondaryFireFlh}getSpecialWeaponFlh(e){return new FlhCoords(this.art.getNumberArray(`Weapon${e+1}FLH`))}get fireUp(){return this.art.getNumber("FireUp")||this.art.getNumber("DelayedFireDelay")}get isAnimDelayedFire(){return this.art.getBool("IsAnimDelayedFire")}get zShapePointMove(){return this.art.getNumberArray("ZShapePointMove")}get zAdjust(){return this.art.getNumber("ZAdjust")}get trailer(){return this.art.getString("Trailer")}get spawnDelay(){return this.art.getNumber("SpawnDelay",1)}get translucent(){return this.art.getBool("Translucent")}get translucency(){var e=(e=this.art.getNumber("Translucency",0))/25*25;return e/=100}}ObjectArt.DEFAULT_LINE_TRAIL_DEC=16,ObjectArt.MISSING_CAMEO="xxicon";class Art{constructor(e,t,i,r){this.rules=e,this.artIni=t,this.mapFile=i,this.logger=r,this.objectArt=new Map,this.parse()}hasObject(e,t){return this.objectArt.get(t)?.has(e)}getObject(e,t){if(!e)throw new Error(`Must specify an art name for type "${ObjectType[t]}"`);var i=this.objectArt.get(t)?.get(e);return i||(this.logger?.debug(`Missing art for object "${e}"`),new ObjectArt(t,this.rules.hasObject(e,t)?this.rules.getObject(e,t):new ObjectRules(t,new IniSection(e)),new IniSection(e)))}getAnimation(e){return this.getObject(e,ObjectType.Animation)}getProjectile(e){var t=this.rules.getProjectile(e),i=t.imageName;let r=this.artIni.getSection(i);return r||(this.logger?.debug(`Image ${i} (Projectile: ${e}) has no section in art.ini`),r=new IniSection(i)),ObjectArt.factory(t.type,t,this.artIni,r)}getIni(){return this.artIni}parse(){this.rules.allObjectRules.forEach((e,t)=>{let r=new Map;this.objectArt.set(t,r),e.forEach(e=>{var t=this.artIni.getSection(e.imageName),i=this.artIni.getSection(e.name);(t=this.applyUnitMapOverrides(e,this.mapFile,i,t))?(t=ObjectArt.factory(e.type,e,this.artIni,t),r.set(e.name,t)):this.logger?.debug(`${ObjectType[e.type]} "${e.name}" has no art section "${e.imageName}"`)})});let e=[[ObjectType.Animation,this.rules.animationNames]];e.forEach(([r,e])=>{let s=new Map;this.objectArt.set(r,s),e.forEach(e=>{var t,i=this.artIni.getSection(e);i?(t=new ObjectRules(r,new IniSection(e)),i=new ObjectArt(r,t,i),s.set(e,i)):this.logger?.debug(ObjectType[r]+` "${e}" has no art section`)})})}applyUnitMapOverrides(e,t,r,s){if([ObjectType.Infantry,ObjectType.Vehicle,ObjectType.Aircraft].includes(e.type)&&!!t?.getSection(e.name)?.getString("Image")&&r){let i=r.clone();s?.entries.forEach((e,t)=>{i.set(t,e)}),s=i,this.logger?.debug(`${ObjectType[e.type]} "${e.name}": `+`Using merged art sections ${e.name} and `+e.imageName)}return s}}class Country{static factory(e,t){return new this(t.getCountry(e))}constructor(e){this.rules=e}get id(){return this.rules.id}get side(){return this.rules.side}get name(){return this.rules.name}isPlayable(){return this.rules.multiplay&&!this.rules.multiplayPassive}hasVeteranUnit(e,t){let i=[];switch(e){case ObjectType.Aircraft:i=this.rules.veteranAircraft;break;case ObjectType.Infantry:i=this.rules.veteranInfantry;break;case ObjectType.Vehicle:i=this.rules.veteranUnits;break;default:throw new Error(`Unsupported object type "${ObjectType[e]}"`)}return i.includes(t)}}class BuildingEvacuateEvent{constructor(e,t){this.target=e,this.player=t,this.type=EventType.BuildingEvacuate}}class GarrisonTrait{constructor(e,t,i){this.building=e,this.evacThreshold=t,this.maxOccupants=i,this.units=[]}isOccupied(){return!!this.units.length}canBeOccupied(){return this.building.healthTrait.health>100*this.evacThreshold}[NotifyDamage.onDamage](e,t){e.healthTrait.health<=100*this.evacThreshold&&this.evacuate(t)}[NotifyDestroy.onDestroy](e,t,i,r){if(r){for(var s of this.units)s.deathType=e.deathType,t.destroyObject(s,i,!0);this.units=[]}else this.evacuate(t)}getHash(){return fnv32a(this.units.map(e=>e.getHash()))}debugGetState(){return{units:this.units.map(e=>e.debugGetState())}}dispose(){this.building=void 0}evacuate(r,s=!1){let a=this.building,n=this.units;if(n.length){let e=new Map;for(var t of n)e.set(t.rules.speedType,(e.get(t.rules.speedType)||[]).concat(t));for(let[t,i]of e){var o,l=new RadialTileFinder(r.map.tiles,r.map.mapBounds,a.tile,a.art.foundation,1,1,e=>0<r.map.terrain.getPassableSpeed(e,t,!0,!1)&&Math.abs(e.z-a.tile.z)<2&&!r.map.terrain.findObstacles({tile:e,onBridge:void 0},i[0]).length).getNextTile();for(o of i){var h=n.indexOf(o);l?(n.splice(h,1),r.unlimboObject(o,l),o.onBridge=r.map.tileOccupation.getBridgeOnTile(l)?.isLowBridge()??!1,o.position.tileElevation=0,o.unitOrderTrait.addTask(new ScatterTask(r))):s||(r.destroyObject(o,{player:o.owner}),n.splice(h,1))}}var i=a.owner;n.length||a.isDestroyed||r.changeObjectOwner(a,r.getCivilianPlayer()),r.events.dispatch(new BuildingEvacuateEvent(a,i))}}}class TurretTrait{constructor(){this.facing=0,this.desiredFacing=0}isRotating(){return this.facing!==this.desiredFacing}[NotifySpawn.onSpawn](e){e.isUnit()&&(this.facing=this.desiredFacing=e.direction)}[NotifyTick_NotifyTick.onTick](e){this.desiredFacing!==this.facing&&(e=e.rules.rot,this.facing=FacingUtil.tick(this.facing,this.desiredFacing,e||Number.POSITIVE_INFINITY).facing)}}class BuildStatusChangeEvent{constructor(e,t){this.target=e,this.status=t,this.type=EventType.BuildStatusChange}}class PowerLowEvent{constructor(e){this.target=e,this.type=EventType.PowerLow}}class PowerRestoreEvent{constructor(e){this.target=e,this.type=EventType.PowerRestore}}class PowerChangeEvent{constructor(e,t,i){this.target=e,this.power=t,this.drain=i,this.type=EventType.PowerChange}}!function(e){e[e.Low=0]="Low",e[e.Normal=1]="Normal"}(PowerLevel=PowerLevel||{});class PowerTrait{constructor(e){this.player=e,this.power=0,this.drain=0,this.level=PowerLevel.Normal,this.blackoutFrames=0,this.powerByObject=new Map}isLowPower(){return this.level===PowerLevel.Low}setBlackoutFor(e,t){var i=0<this.blackoutFrames;this.blackoutFrames=e,i||this.updateLevel(t)}updateBlackout(e){0<this.blackoutFrames&&(this.blackoutFrames--,this.blackoutFrames<=0&&this.updateLevel(e))}getBlackoutDuration(){return this.blackoutFrames}updateFrom(t,i,r){var s=t.rules.power;if(s){if(s<0)"add"!==i&&"remove"!==i||(this.drain+="add"===i?-s:s);else{let e=0;if("add"===i){var a=Math.ceil(s*t.healthTrait.health/100);this.powerByObject.set(t,a),e=a}else if("update"===i||"remove"===i){a=this.powerByObject.get(t);if(void 0===a)throw new Error("Cannot update power before add.");e="update"===i?(s=Math.ceil(s*t.healthTrait.health/100),this.powerByObject.set(t,s),s-a):(this.powerByObject.delete(t),-a)}this.power+=e}this.updateLevel(r),r.traits.filter(NotifyPower).forEach(e=>{e[NotifyPower.onPowerChange](this.player,r)}),r.events.dispatch(new PowerChangeEvent(this.player,this.power,this.drain))}}updateLevel(t){var e=this.level;this.level=this.power>=this.drain&&!this.blackoutFrames?PowerLevel.Normal:PowerLevel.Low,this.level!==e&&(e===PowerLevel.Normal&&this.level===PowerLevel.Low&&(t.traits.filter(NotifyPower).forEach(e=>{e[NotifyPower.onPowerLow](this.player,t)}),t.events.dispatch(new PowerLowEvent(this.player))),e===PowerLevel.Low&&this.level===PowerLevel.Normal&&(t.traits.filter(NotifyPower).forEach(e=>{e[NotifyPower.onPowerRestore](this.player,t)}),t.events.dispatch(new PowerRestoreEvent(this.player))))}getHash(){return fnv32a([this.power,this.drain])}debugGetState(){return{power:this.power,drain:this.drain}}dispose(){this.player=void 0,this.powerByObject.clear()}}class PoweredTrait{constructor(e){this.obj=e,this.turnedOn=!0}setTurnedOn(e){this.turnedOn=e}isCharged(){return!!this.obj.isBuilding()&&!!this.obj.overpoweredTrait?.hasChargersToPowerOn()}isPoweredOn(e=!1){return!(!this.obj||!this.turnedOn)&&(!(e||!this.isCharged())||(!this.obj.rules.power&&this.obj.rules.needsEngineer?!this.obj.owner.isNeutral:!!this.obj.owner.powerTrait&&this.obj.owner.powerTrait?.level!==PowerLevel.Low))}dispose(){this.obj=void 0}}class EventDispatcher{constructor(){this.listeners=new Set}subscribe(e){this.listeners.add(e)}subscribeOnce(i){let r=(e,t)=>{i(e,t),this.unsubscribe(r),r=void 0};this.subscribe(r)}unsubscribe(e){this.listeners.delete(e)}dispatch(t,i){this.listeners.forEach(e=>e(i,t))}asEvent(){return this}}!function(e){e[e.Structures=0]="Structures",e[e.Armory=1]="Armory",e[e.Infantry=2]="Infantry",e[e.Vehicles=3]="Vehicles",e[e.Aircrafts=4]="Aircrafts",e[e.Ships=5]="Ships"}(QueueType=QueueType||{}),function(e){e[e.Idle=0]="Idle",e[e.Active=1]="Active",e[e.OnHold=2]="OnHold",e[e.Ready=3]="Ready"}(QueueStatus=QueueStatus||{});class ProductionQueue{get onUpdate(){return this._onUpdate.asEvent()}constructor(e,t,i){this.type=e,this._maxSize=t,this.maxItemQuantity=i,this.items=[],this.size=0,this._status=QueueStatus.Idle,this._onUpdate=new EventDispatcher}get status(){return this._status}set status(e){var t=this._status;(this._status=e)!==t&&this._onUpdate.dispatch(this)}get maxSize(){return this._maxSize}set maxSize(e){var t=this.size;this.size=Math.min(e,this.size);let i=0,r=0;for(;i<=this.size&&r<this.items.length;){let e=this.items[r];i+=e.quantity,i>this.size&&(e.quantity-=i-this.size),0<e.quantity&&r++}this._maxSize=e,this.items[r]&&this.items.splice(r),t!==this.size&&(this.size||(this._status=QueueStatus.Idle),this._onUpdate.dispatch(this))}get currentSize(){return this.size}find(t){return this.items.filter(e=>e.rules===t)}getFirst(){return this.items[0]}getAll(){return[...this.items]}push(e,t,i){t=Math.min(this.maxSize-this.size,t);var r=this.find(e).reduce((e,t)=>e+t.quantity,0);(t=Math.min(this.maxItemQuantity-r,t))&&(this.items[this.items.length-1]?.rules===e?this.items[this.items.length-1].quantity+=t:this.items.push({rules:e,quantity:t,creditsEach:i,creditsSpent:0,creditsSpentLeftover:0,progress:0}),this.size+=t,this._status===QueueStatus.Idle&&(this._status=QueueStatus.Active),this._onUpdate.dispatch(this))}insertAfterFirst(t,i,r){i=Math.min(this.maxSize-this.size,i);var s=this.find(t).reduce((e,t)=>e+t.quantity,0);if(i=Math.min(this.maxItemQuantity-s,i))if(this.items.length){let e=this.items[0];var a=e.quantity,s=Math.max(0,a-1);e.quantity=1;const n=[e];a=this.items.slice(1);n.push({rules:t,quantity:i,creditsEach:r,creditsSpent:0,creditsSpentLeftover:0,progress:0}),0<s&&n.push({rules:e.rules,quantity:s,creditsEach:e.creditsEach,creditsSpent:0,creditsSpentLeftover:0,progress:0}),n.push(...a),this.items=n,this.size+=i,this._status===QueueStatus.Idle&&(this._status=QueueStatus.Active),this._onUpdate.dispatch(this)}else this.push(t,i,r)}pop(e,t){this.remove(e,t,!1)}shift(e,t){this.remove(e,t,!0)}remove(e,t,i){let r=this.find(e);if(!r.length)throw new Error(`Can't remove non-existent item ${e.name} from queue `+QueueType[this.type]);var s;if(r.reduce((e,t)=>e+t.quantity,0)<t)throw new Error(`Attempted to remove a quantity larger than the one in queue (${e.name})`);let a=t;for(;0<a;){let e=i?r.shift():r.pop();e.quantity<=a?(s=this.getFirst()===e,this.items.splice(this.items.indexOf(e),1),s&&(this._status=QueueStatus.Active),a-=e.quantity):(e.quantity-=a,a=0)}this.size-=t,t&&(this.size||(this._status=QueueStatus.Idle),this._onUpdate.dispatch(this))}notifyUpdated(){this._onUpdate.dispatch(this)}}const LosHelper_isGameObject=e=>void 0!==e.position;class LosHelper{constructor(e,t){this.tiles=e,this.tileOccupation=t}hasLineOfSight(t,i,r){var s=r.warhead.rules.wall||!r.projectileRules.subjectToWalls,a=r.projectileRules.subjectToCliffs,n=r.rules.spawner;let o=0,l=!1;if(!s||a||n){var h,c,r=LosHelper_isGameObject(t)?t.tile:t,i=LosHelper_isGameObject(i)?i.isBuilding()?i.centerTile:i.tile:i;let e=r.z;a&&LosHelper_isGameObject(t)&&t.isUnit()&&t.onBridge&&(e+=this.tileOccupation.getBridgeOnTile(r)?.tileElevation??0);for({x:h,y:c}of bresenham(r.rx,r.ry,i.rx,i.ry)){var u=this.tiles.getByMapCoords(h,c);if(!u)return!1;if(!s&&u.landType===LandType.Wall)return!1;if(a)if(u.landType===LandType.Cliff){if(u.z>e)return!1;l=!0}else{if(u.z>e&&l)return!1;l=!1}if(n&&o<2&&this.tileOccupation.getBridgeOnTile(u)?.isHighBridge())return!1;o++}}return!0}}const STRAFE_CLOSE_ENOUGH=2,BOMBER_RETURN_TILES=7;class MoveInWeaponRangeTask extends MoveTask{constructor(e,t,i,r){super(e,t instanceof GameObject?t.isBuilding()?t.centerTile:t.tile:t,i,{pathFinderIgnoredBlockers:t instanceof GameObject&&0<r.range?[t]:void 0}),this.target=t,this.weapon=r,this.recalcMinRange=!0,this.cancelRequested=!1,this.bomberInitialLock=!1,this.rangeHelper=new RangeHelper(e.map.tileOccupation),this.losHelper=new LosHelper(e.map.tiles,e.map.tileOccupation)}onStart(i){let e=this.target,r=this.game.map;if(e instanceof GameObject&&e.isBuilding()&&i.rules.movementZone!==MovementZone.Fly){let t=e.tile;var s=e instanceof GameObject?e.getFoundation():{width:1,height:1},s=new RadialTileFinder(r.tiles,r.mapBounds,t,s,1,5,e=>0<r.terrain.getPassableSpeed(e,i.rules.speedType,i.isInfantry(),!1)&&Math.abs(e.z-t.z)<2).getNextTile();s&&this.rangeHelper.tileDistance(e,s)>Math.SQRT2&&this.updateTarget(s,!1)}this.bomberInitialLock=this.isCloseEnoughToDest(i,i.tile),super.onStart(i)}cancel(){this.bomberManeuverTile?this.cancelRequested=!0:super.cancel()}shouldAirStrafe(e){return e.rules.movementZone===MovementZone.Fly&&e.rules.locomotor===LocomotorType.Aircraft&&e.rules.fighter&&1<this.weapon.projectileRules.iniRot}isBombingRun(e){return e.rules.movementZone===MovementZone.Fly&&e.rules.locomotor===LocomotorType.Aircraft&&this.weapon.projectileRules.iniRot<=1}isAirStrafeCloseEnough(e){return this.rangeHelper.tileDistance(e,this.targetTile)<Math.min(this.weapon.range,STRAFE_CLOSE_ENOUGH)}bomberCanReturn(e){return!this.bomberManeuverTile||this.rangeHelper.tileDistance(e,this.bomberManeuverTile)<=1}findStrafeDestination(t,i){let e=new RandomTileFinder(this.game.map.tiles,this.game.map.mapBounds,i,this.weapon.range,this.game,e=>this.rangeHelper.isInWeaponRange(t,i,this.weapon,this.game.rules,e));return e.getNextTile()}hasReachedDestination(e){return super.hasReachedDestination(e)||this.canStopAtTile(e,e.tile,e.onBridge)}canStopAtTile(t,e,i){if(t.zone!==ZoneType.Air&&this.target instanceof GameObject&&this.game.map.tileOccupation.isTileOccupiedBy(e,this.target)&&(!this.target.isUnit()||this.target.tile===e&&this.target.moveTrait.moveState!==MoveState.Moving&&this.target.position.subCell===t.position.subCell))return!1;if(t.zone!==ZoneType.Air){if(!super.canStopAtTile(t,e,i))return!1}else if(this.game.map.tileOccupation.getAirObjectsOnTile(e).filter(e=>e.isUnit()&&e.moveTrait.moveState!==MoveState.Moving&&e!==t).length)return!1;return!(this.isBombingRun(t)&&!this.bomberCanReturn(e))&&(!!this.isCancelling()||this.isCloseEnoughToDest(t,e))}isCloseEnoughToDest(e,t){if(e.rules.balloonHover&&!e.rules.hoverAttack)return this.rangeHelper.isInTileRange(t,this.target,0,0);if(this.weapon.rules.cellRangefinding||!e.isInfantry())return this.rangeHelper.isInWeaponRange(e,this.target,this.weapon,this.game.rules,t)&&this.losHelper.hasLineOfSight(t,this.target,this.weapon);var i=e.zone===ZoneType.Air?e.position.computeSubCellOffset(e.position.desiredSubCell):e.position.getTileOffset(),{minRange:r,range:s}=this.rangeHelper.computeWeaponRangeVsTarget(t,this.target,this.weapon,this.game.rules),i=Coords.tile3dToWorld(t.rx+i.x/Coords.LEPTONS_PER_TILE,t.ry+i.y/Coords.LEPTONS_PER_TILE,t.z+e.position.tileElevation);return(e.isUnit()&&e.rules.movementZone===MovementZone.Fly?this.rangeHelper.isInRange2(i,this.target,r,s):this.rangeHelper.isInRange3(i,this.target,r,s))&&this.losHelper.hasLineOfSight(t,this.target,this.weapon)}findRelocationTile(t,i,r){if(r.rules.movementZone!==MovementZone.Fly)return super.findRelocationTile(t,i,r);{i=this.game.map;let e=new RandomTileFinder(i.tiles,i.mapBounds,t,1,this.game,e=>this.isCancelling()||this.isCloseEnoughToDest(r,e));return e.getNextTile()}}retarget(e,t){var i=e instanceof GameObject?e.isBuilding()?e.centerTile:e.tile:e;this.bomberManeuverTile?this.bomberQueuedTargetTile=i:(this.updateTarget(i,t),this.recalcMinRange=!0),this.target=e,this.options?.ignoredBlockers&&(this.options.ignoredBlockers=e instanceof GameObject?[e]:void 0),this.options??(this.options={}),this.options.pathFinderIgnoredBlockers=e instanceof GameObject?[e]:void 0}onTick(s){if(this.recalcMinRange){this.recalcMinRange=!1;var e=this.findMinRangeRelocationTile(s,this.targetTile);if(e!==this.targetTile){if(!e)return this.cancel(),!1;this.updateTarget(e,!!e.onBridgeLandType)}}if(this.shouldAirStrafe(s)&&!this.isCancelling()&&(this.updateTarget(this.target instanceof GameObject?this.target.isBuilding()?this.target.centerTile:this.target.tile:this.target,!1),!this.isAirStrafeCloseEnough(s)||(a=this.findStrafeDestination(s,this.targetTile))&&this.updateTarget(a,!1)),this.isBombingRun(s)&&!this.isCancelling()&&(!s.ammo||this.weapon.getBurstsFired()||this.bomberInitialLock)&&!this.bomberManeuverTile){this.bomberInitialLock=!1;let e=s.position.getMapPosition();var a=this.target instanceof GameObject?this.target.isBuilding()?this.target.centerTile:this.target.tile:this.target;let t=new Vector2(a.rx+.5,a.ry+.5).clone().multiplyScalar(Coords.LEPTONS_PER_TILE).sub(e),i=t.length();i||(t.copy(FacingUtil.toMapCoords(s.direction)),i=Number.EPSILON);let r=e.clone().add(t.setLength(i+BOMBER_RETURN_TILES*Coords.LEPTONS_PER_TILE));a=r.multiplyScalar(1/Coords.LEPTONS_PER_TILE).floor(),a=bresenham(a.x,a.y,s.tile.rx,s.tile.ry);if(!a.length)throw new Error("Bresenham returned no tiles");a=a[0];this.bomberManeuverTile=this.game.map.tiles.getByMapCoords(a.x,a.y)??this.game.map.tiles.getPlaceholderTile(a.x,a.y),this.options.allowOutOfBoundsTarget=!0,this.updateTarget(this.bomberManeuverTile,!1)}return this.bomberManeuverTile&&this.bomberCanReturn(s.tile)&&(this.bomberManeuverTile=void 0,this.bomberQueuedTargetTile&&(this.updateTarget(this.bomberQueuedTargetTile,!1),this.recalcMinRange=!0,this.bomberQueuedTargetTile=void 0)),this.cancelRequested&&(this.bomberManeuverTile||(this.cancelRequested=!1,this.cancel())),!!(this.isBombingRun(s)&&this.isCancelling()&&this.forceCancel(s))||super.onTick(s)}forceCancel(e){return!this.bomberManeuverTile&&super.forceCancel(e)}findMinRangeRelocationTile(e,t){var{minRange:i,range:r}=this.rangeHelper.computeWeaponRangeVsTarget(e,this.target,this.weapon,this.game.rules);return e.rules.locomotor===LocomotorType.Chrono?this.rangeHelper.isInRange(e,this.target,r-1,r,this.weapon.rules.cellRangefinding)?t:this.findTileInRange(e,t,r-1,2*r)??t:this.rangeHelper.isInRange(e,this.target,i,Number.POSITIVE_INFINITY,this.weapon.rules.cellRangefinding)?t:this.findTileInRange(e,t,2*i,r-i)}findTileInRange(t,e,i,r){let s=this.game.map;var a,i=new Vector2(t.tile.rx-e.rx,t.tile.ry-e.ry).setLength(i).floor().add(new Vector2(e.rx,e.ry));let n;for(a of bresenham(i.x,i.y,e.rx,e.ry))if(n=s.tiles.getByMapCoords(a.x,a.y),n)break;if(n){let e=new RadialTileFinder(s.tiles,s.mapBounds,n,{width:1,height:1},0,r,e=>this.rangeHelper.isInWeaponRange(t,this.target,this.weapon,this.game.rules,e)&&this.losHelper.hasLineOfSight(e,this.target,this.weapon)&&0<s.terrain.getPassableSpeed(e,t.rules.speedType,t.isInfantry(),!!e.onBridgeLandType)&&!s.terrain.findObstacles({tile:e,onBridge:!!e.onBridgeLandType},t).length);return e.getNextTile()}}}class TaskRunner{tick(e,t){this.tickChildren(e,t)}startTask(e,t){if(e.status!==TaskStatus.NotStarted)throw new Error("Attempted to start a task with status "+e.status);e.status=TaskStatus.Running,e.onStart(t)}tickTask(e,t){let i=this.tickChildren(e.children,t);var r=e.children.find(e=>e.blocking);if(!i&&r)return!1;if(!t.isSpawned)return!1;if(e.status===TaskStatus.NotStarted)throw new Error("Attempted tick on a non-started task");if(e.isRunning()||e.isCancelling()){var s=e.isCancelling(),a=!!e.waitingForChildrenToFinish||e.onTick(t);e.children.length&&!r&&a&&(i=e.children.every(e=>e.status===TaskStatus.Cancelled||e.status===TaskStatus.Finished),e.waitingForChildrenToFinish=!i);a=a&&i;return a&&(e.onEnd(t),e.status=s?TaskStatus.Cancelled:TaskStatus.Finished),a}return!0}tickChildren(r,s){let a=!0;if(r.length){let t=new Set,i;for(;s.isSpawned&&(i=r.find(e=>!t.has(e)));){let e;if(i.status===TaskStatus.NotStarted&&this.startTask(i,s),i.status===TaskStatus.Running||i.status===TaskStatus.Cancelling)e=!0===this.tickTask(i,s);else{if(i.status!==TaskStatus.Cancelled)throw new Error("Unhandled task status "+TaskStatus[i.status]);e=!0}if(e){var n=r.indexOf(i);-1!==n&&r.splice(n,1)}else{if(a=!1,i.blocking)break;t.add(i)}}}return a}}class Target{constructor(e,t,i){this.tileOccupation=i,this.isOre=!1,e?e.isOverlay()&&e.isBridge()?(this.bridge=e,this.tile=t):e.isOverlay()&&e.isTiberium()?(this.isOre=!0,this.tile=e.tile):(this.obj=e,this.tile=e.isBuilding()?e.centerTile:e.tile):(t.landType===LandType.Tiberium&&(this.isOre=!0),this.tile=t)}equals(e){return this.obj===e.obj&&this.tile===e.tile&&this.bridge===e.bridge&&this.isOre===e.isOre}getWorldCoords(){return this.obj?this.obj.position.worldPosition:Coords.tile3dToWorld(this.tile.rx+.5,this.tile.ry+.5,this.tile.z+(this.bridge?.tileElevation??0))}isBridge(){return!this.obj&&!!this.bridge}getBridge(){return this.bridge||(this.obj?.isUnit()&&this.obj.onBridge?this.tileOccupation.getBridgeOnTile(this.obj.tile):void 0)}}const SCAN_TARGET_FOUNDATION_ADJUST=3;!function(e){e[e.Idle=0]="Idle",e[e.CheckRange=1]="CheckRange",e[e.PrepareToFire=2]="PrepareToFire",e[e.FireUp=3]="FireUp",e[e.Firing=4]="Firing",e[e.JustFired=5]="JustFired"}(AttackState=AttackState||{});class AttackTrait{constructor(e,t){this.disabled=!1,this.attackState=AttackState.Idle,this.passiveScanCooldownTicks=0,this.taskRunner=new TaskRunner,this.distributedFireHistory=new Map,this.rangeHelper=new RangeHelper(t),this.losHelper=new LosHelper(e,t)}isIdle(){return this.attackState===AttackState.Idle}isDisabled(){return this.disabled}setDisabled(e){this.disabled=e}isOnCooldown(e){let t=[e.primaryWeapon,e.secondaryWeapon],i=e.armedTrait?.getDeployFireWeapon();return i?.rules.areaFire&&!i.rules.fireOnce&&(t=t.filter(e=>e!==i)),t.some(e=>0<(e?.getCooldownTicks()??0))}expirePassiveScanCooldown(){this.passiveScanCooldownTicks=0}increasePassiveScanCooldown(e){this.passiveScanCooldownTicks+=e}cancelOpportunityFire(){this.opportunityFireTask?.cancel()}getOpportunityFireTask(){return this.opportunityFireTask}selectDefaultWeapon(e){let i;if((e.isInfantry()||e.isVehicle())&&e.rules.deployFire){let t=e.armedTrait?.getDeployFireWeapon();i=e.deployerTrait?.isDeployed()?t&&!t.rules.areaFire?t:void 0:[e.primaryWeapon,e.secondaryWeapon].find(e=>e!==t)}else i=e.isBuilding()&&e.garrisonTrait?e.garrisonTrait.isOccupied()?e.owner.country.side===SideType.GDI?e.primaryWeapon:e.secondaryWeapon??e.primaryWeapon:void 0:e.isBuilding()&&e.overpoweredTrait?e.overpoweredTrait.getWeapon():e.primaryWeapon;return i}selectWeaponVersus(e,t,i,r=!1,s=!1){var a=t.tile;const n=t instanceof Target?t.obj:t;t=this.getAvailableWeapons(e,s,n?.isOverlay()||r&&!n);return this.selectWeaponFromList(e,n,a,t,i,r,s,!1)}selectWeaponFromList(e,t,i,r,s,a,n,o){if((!t?.isInfantry()&&!t?.isVehicle()||!t.disguiseTrait||this.canAttackThroughDisguise(e,t,t.disguiseTrait,s,a,n,o))&&(t?.isBuilding()&&t.overpoweredTrait&&t.owner===e.owner&&r.find(e=>e.warhead.rules.electricAssault)&&(r=r.filter(e=>e.warhead.rules.electricAssault)),!(n&&t?.isAircraft()&&t.missileSpawnTrait&&t.zone!==ZoneType.Air))){var l=t?.isTechno()?t.rules.armor:void 0;for(const h of r)if(h.targeting.canTarget(t,i,s,a,n)&&(void 0===l||this.checkArmor(h.warhead.rules,l,n)))return h}}getAvailableWeapons(e,t,i){let r;var s;return r=(e.isInfantry()||e.isVehicle())&&e.rules.deployFire&&e.armedTrait?(s=e.armedTrait.getDeployFireWeapon(),[e.deployerTrait?.isDeployed()?s.rules.areaFire?void 0:s:s===e.secondaryWeapon?e.primaryWeapon:e.secondaryWeapon]):e.isBuilding()&&e.garrisonTrait?e.garrisonTrait.isOccupied()?[e.owner.country.side===SideType.GDI?e.primaryWeapon:e.secondaryWeapon??e.primaryWeapon]:[]:e.isBuilding()&&e.overpoweredTrait?[e.overpoweredTrait.getWeapon()]:i||t?[e.primaryWeapon,!i&&t&&e.secondaryWeapon?e.secondaryWeapon:void 0]:[e.primaryWeapon,e.secondaryWeapon],r.filter(e=>e&&!e.rules.neverUse)}canAttackThroughDisguise(e,t,i,r,s,a,n){if(!s&&i.hasTerrainDisguise()&&!r.areFriendly(e,t)&&!e.owner.sharedDetectDisguiseTrait?.has(t))return!1;if(a){if(n&&t.moveTrait.isIdle()&&!e.rules.detectDisguise&&!e.owner.sharedDetectDisguiseTrait?.has(t)&&!r.areFriendly(t,e))return!1;i=i.getDisguise();if(i?.owner&&!e.rules.detectDisguise&&!e.owner.sharedDetectDisguiseTrait?.has(t)&&(i.owner===e.owner||r.alliances.areAllied(e.owner,i.owner)))return!1}return!0}checkArmor(e,t,i){var r=e.ivanBomb||e.bombDisarm||e.nukeMaker?1:e.verses.get(t);return void 0===r?(console.warn(`Unhandled ArmorType ${ArmorType[t]} in warhead ${e.name} verses`),!1):!(100*r<=(i?1:0))}createAttackTask(e,t,i,r,s){return new AttackTask(e,e.createTarget(t,i),r,s)}[NotifyTick_NotifyTick.onTick](a,n){if(!this.isDisabled()){if(this.opportunityFireTask&&(!a.unitOrderTrait.hasTasks()||a.isUnit()&&!a.unitOrderTrait.getTasks()[0].preventOpportunityFire||(a.unitOrderTrait.getTasks()[0]instanceof AttackTask?this.opportunityFireTask=void 0:this.opportunityFireTask.cancel()),this.opportunityFireTask&&(c=[this.opportunityFireTask],this.taskRunner.tick(c,a),c.length||(this.opportunityFireTask=void 0))),!this.opportunityFireTask&&this.retaliateTarget){var o=this.retaliateTarget;this.retaliateTarget=void 0;let e;!a.unitOrderTrait.hasTasks()&&n.isValidTarget(o)&&(e=this.selectWeaponVersus(a,o,n,!1))&&a.unitOrderTrait.addTask(this.createAttackTask(n,o,o.tile,e,{holdGround:a.rules.movementZone===MovementZone.Fly}))}if(!this.opportunityFireTask&&this.shouldPassiveAcquire(a))if(0<this.passiveScanCooldownTicks)this.passiveScanCooldownTicks--;else{this.passiveScanCooldownTicks=a.guardMode?n.rules.general.guardAreaTargetingDelay:n.rules.general.normalTargetingDelay;let e=this.selectDefaultWeapon(a);var l,h,c=a.unitOrderTrait.hasTasks();let t=void 0,i,r;!c&&a.guardMode&&e&&a.owner.isCombatant()&&(t=a.armedTrait?.computeGuardScanRange(e),i=a.guardArea?.tile,r=50);let s=!1;!e||(o=this.scanForTarget(a,e,n,t,i)).target&&({target:l,weapon:h}=o,l=this.createAttackTask(n,l,l.tile,h,{holdGround:c||!a.guardMode,disallowTurning:c,leashTiles:r,passive:!0}),c?this.opportunityFireTask=l:a.unitOrderTrait.addTask(l),s=!0,c||!a.guardMode||a.guardArea||(a.guardArea={tile:a.tile,onBridge:!!a.isUnit()&&a.onBridge}),s&&!c&&a.unitOrderTrait[NotifyTick_NotifyTick.onTick](a,n)),s||c||!a.secondaryWeapon?.warhead.rules.electricAssault||(e=a.secondaryWeapon,(h=this.scanForTarget(a,e,n,void 0,void 0,!0)).target&&({target:l,weapon:h}=h,h=this.createAttackTask(n,l,l.tile,h,{passive:!0}),a.unitOrderTrait.addTask(h),s=!0)),!s&&!c&&a.guardArea&&a.isUnit()&&a.moveTrait&&!a.moveTrait.isDisabled()&&a.guardArea.tile!==a.tile&&a.unitOrderTrait.addTasks(new MoveTask(n,a.guardArea.tile,a.guardArea.onBridge),new CallbackTask(()=>{[MoveResult.Success,MoveResult.CloseEnough].includes(a.moveTrait.lastMoveResult)||a.resetGuardModeToIdle(),a.guardArea=void 0}))}}}[NotifyDamage.onDamage](e,t,i,r){this.isDisabled()||!this.retaliateTarget&&!this.opportunityFireTask&&r&&r.obj&&r.weapon&&this.shouldRetaliate(e,t,i,r.obj,r.weapon.warhead)&&(this.retaliateTarget=r.obj)}[NotifyTeleport.onBeforeTeleport](e,t,i,r){r||(this.attackState=AttackState.Idle,this.currentTarget=void 0,this.retaliateTarget=void 0,this.opportunityFireTask=void 0)}shouldPassiveAcquire(e){if(!e.owner.isCombatant()&&e.rules.needsEngineer||!e.rules.canPassiveAquire||!e.primaryWeapon||e.ammoTrait&&!e.ammoTrait.ammo&&e.rules.manualReload)return!1;if(e.mindControllerTrait?.isAtCapacity())return!1;var t=e.rules.opportunityFire||e.rules.balloonHover&&e.unitOrderTrait.getCurrentTask()?.isAttackMove;if(e.isUnit()&&t){if(e.unitOrderTrait.hasTasks()&&e.unitOrderTrait.getTasks()[0].preventOpportunityFire)return!1}else if(e.unitOrderTrait.hasTasks())return!1;return!0}shouldRetaliate(e,t,i,r,s){if(i<1||t.areFriendly(e,r)||!e.rules.canRetaliate||!e.primaryWeapon||e.ammoTrait&&!e.ammoTrait.ammo&&e.rules.manualReload||s.rules.temporal||r.rules.missileSpawn||e.unitOrderTrait.hasTasks()||!t.isValidTarget(r)||(r.isInfantry()||r.isVehicle())&&r.disguiseTrait&&!e.rules.detectDisguise||e.mindControllerTrait?.isAtCapacity())return!1;t=this.selectWeaponVersus(e,r,t,!1);return!(!t||(e.isBuilding()||r.isBuilding()?this.rangeHelper.tileDistance(e,r):this.rangeHelper.distance2(e,r)/Coords.LEPTONS_PER_TILE)>Math.max(t.range,e.sight))}scanForTarget(e,t,i,r,s,a=!1){let n={},o=Number.NEGATIVE_INFINITY;var l=this.getAvailableWeapons(e,!0,!1),t=r??(e.rules.guardRange||t.range)+1+SCAN_TARGET_FOUNDATION_ADJUST+i.rules.elevationModel.bonusCap+(t.projectileRules.isAntiAir?e.rules.airRangeBonus:0);for(const u of this.scanTechnosAround(e,t,i)){var h,c=this.selectWeaponFromList(e,u,u.tile,l,i,!1,!0,!0);c&&this.canPassiveAcquire(u,i)&&i.isValidTarget(u)&&(r?this.rangeHelper.isInRange(e,u,c.minRange,r,c.rules.cellRangefinding)&&(!s||this.rangeHelper.isInRange2(s,u,0,r)):this.rangeHelper.isInWeaponRange(e,u,c,i.rules))&&(a||this.losHelper.hasLineOfSight(e,u,c))&&(h=this.rangeHelper.distance3(e,u)/Coords.LEPTONS_PER_TILE,(h=this.computeThreat(u,e,c,h,i.rules.general.threat))>o&&(n={target:u,weapon:c},o=h))}return n.target&&e.rules.distributedFire&&this.updateDistributedFireHistory(n),n}scanTechnosAround(e,t,i){var r=e.getFoundation();const s=new Vector2(e.tile.rx,e.tile.ry),a=new Vector2(e.tile.rx+r.width-1,e.tile.ry+r.height-1);s.addScalar(-t),a.addScalar(t);t=new Box2(s,a);return i.map.technosByTile.queryRange(t)}canPassiveAcquire(e,t){return!e.owner.isNeutral&&!e.rules.civilian&&(!e.rules.insignificant||e.isBuilding()&&e.garrisonTrait?.isOccupied())&&(1<e.rules.threatPosed||e.isBuilding()&&e.garrisonTrait?.isOccupied()||0<e.rules.specialThreatValue&&!e.isBuilding()||e.rules.harvester||e.name===t.rules.general.paradrop.paradropPlane)}computeThreat(e,t,i,r,s){let a=[e.primaryWeapon,e.secondaryWeapon].filter(isNotNullOrUndefined).map(e=>e.warhead.rules.verses.get(t.rules.armor)??0).reduce((e,t)=>Math.max(e,t),0)*s.targetEffectivenessCoefficientDefault;return e.attackTrait?.currentTarget?.obj===t&&(a*=-1),a+=e.rules.specialThreatValue*s.targetSpecialThreatCoefficientDefault,a+=(i.warhead.rules.verses.get(e.rules.armor)??0)*s.myEffectivenessCoefficientDefault,a+=e.healthTrait.health/100*s.targetStrengthCoefficientDefault,a+=r*s.targetDistanceCoefficientDefault,a+=1e5,t.rules.vhpScan!==VhpScan.None&&(s=e.healthTrait.getProjectedHitPoints(),t.rules.vhpScan===VhpScan.Strong?s<=0&&(a=Number.NEGATIVE_INFINITY):t.rules.vhpScan===VhpScan.Normal&&(s<=0?a/=2:s<=e.healthTrait.maxHitPoints/2&&(a*=2))),t.rules.distributedFire&&(a-=1e6*(this.distributedFireHistory.get(e)??0)),a}updateDistributedFireHistory(e){if(50!==this.distributedFireHistory.get(e.target)){for(var[t,i]of this.distributedFireHistory)i--,i<=0?this.distributedFireHistory.delete(t):this.distributedFireHistory.set(t,i);this.distributedFireHistory.set(e.target,50)}}dispose(){this.distributedFireHistory.clear()}}const MAX_MOVE_ATTEMPTS=3,FACING_DELTA_NONHOMING_THRESH_DEG=11.25,FACING_DELTA_HOMING_THRESH_DEG=4*FACING_DELTA_NONHOMING_THRESH_DEG;class AttackTask extends Task{constructor(e,t,i,r={}){super(),this.game=e,this.target=t,this.weapon=i,this.options=r,this.moveExecuted=!1,this.moveAttempts=0,this.rangeCheckCooldown=0,this.lastInRangeTargetPosition=new Vector3_Vector3,this.lastInRangeSelfPosition=new Vector3_Vector3,this.initialIndirectTarget=!1,this.forceDropTarget=!1,this.rangeHelper=new RangeHelper(e.map.tileOccupation),this.losHelper=new LosHelper(e.map.tiles,e.map.tileOccupation),this.targetLinesConfig={pathNodes:[]},this.updateTargetLines(this.target,!0)}duplicate(){return new AttackTask(this.game,this.target,this.weapon,this.options)}getWeapon(){return this.weapon}setWeapon(e){this.weapon=e}setForceAttack(e){this.options.force=e}requestTargetUpdate(e){this.target.equals(e)||(this.needsTargetUpdate=e)}onTargetChange(e){let t=e.attackTrait,i=this.target;t.currentTarget=i,this.lastValidTargetPosition=i.obj?{tile:i.tile,onBridge:i.getBridge()}:void 0,this.initialTargetOwner=i.obj?.isTechno()?i.obj.owner:void 0,this.initialIndirectTarget=!i.obj&&this.game.map.tileOccupation.getObjectsOnTile(i.tile).some(e=>e.isOverlay()&&!e.isBridgePlaceholder()||e.isTerrain()),this.updateTargetLines(i,!0)}updateTargetLines(e,t){this.targetLinesConfig.target=e.obj,this.targetLinesConfig.pathNodes=e.obj?[]:[{tile:e.tile,onBridge:e.getBridge()}],this.targetLinesConfig.isAttack=t}onStart(t){if(!t.attackTrait)throw new Error(`Object ${t.name} has no attack trait`);if(0!==t.ammo){let e=this.game.map.tileOccupation;var i,r;t.attackTrait.attackState=AttackState.CheckRange,this.onTargetChange(t),this.initialSelfPosition={tile:t.tile,onBridge:t.isUnit()&&t.onBridge?e.getBridgeOnTile(t.tile):void 0},this.weapon.rules.limboLaunch&&t.isUnit()&&!this.target.obj&&(this.forceDropTarget=!0,{reachable:i,fallback:r}=this.findReachableMeleePosition(this.target.tile,!!this.target.getBridge(),{width:1,height:1},t),!i&&r&&(this.lastValidTargetPosition=r,this.updateTargetLines(this.game.createTarget(r.onBridge,r.tile),!1))),this.weapon.rules.limboLaunch&&this.target.obj?.isTechno()&&t.isUnit()&&!this.rangeHelper.isInWeaponRange(t,this.target.obj,this.weapon,this.game.rules)&&({reachable:i,fallback:r}=this.findReachableMeleePosition(this.target.obj.tile,this.target.obj.isUnit()&&this.target.obj.onBridge,this.target.obj.getFoundation(),t),i||(1<(t.unitOrderTrait.waypointPath?.waypoints?.length??0)?this.cancel():(this.forceDropTarget=!0,r&&(this.lastValidTargetPosition=r,this.updateTargetLines(this.game.createTarget(r.onBridge,r.tile),!1))))),this.rangeHelper.isInWeaponRange(t,this.target.obj??this.target.tile,this.weapon,this.game.rules)&&t.isUnit()&&t.rules.movementZone===MovementZone.Fly&&t.zone!==ZoneType.Air&&(t.rules.hoverAttack||t.isAircraft())&&this.children.push(new MoveTask(this.game,t.tile,!1).setCancellable(!1))}else this.cancel()}findReachableMeleePosition(r,e,t,s){let i=this.game.map,a=i.tileOccupation,n=e?a.getBridgeOnTile(r):void 0,o=new MovePositionHelper(i),l=s.rules.movementZone===MovementZone.Fly,h=(e,t)=>l||0<i.terrain.getPassableSpeed(e,s.rules.speedType,s.isInfantry(),!!t)&&o.isEligibleTile(e,t,n,r)&&!i.terrain.findObstacles({tile:e,onBridge:t},s).length,c,u=new RadialTileFinder(i.tiles,i.mapBounds,r,t,1,Math.ceil(this.weapon.rules.range),e=>{let t=!1;var i;return h(e,void 0)&&(c=c??{tile:e,onBridge:void 0},t=!0),void 0!==e.onBridgeLandType&&(i=a.getBridgeOnTile(e),h(e,i)&&(c=c??{tile:e,onBridge:i},t=!0)),!!t&&this.rangeHelper.isInWeaponRange(s,r,this.weapon,this.game.rules,e)});return{reachable:u.getNextTile(),fallback:c}}onEnd(e){e.isVehicle()&&e.turretTrait&&(e.turretTrait.desiredFacing=e.direction),e.attackTrait.attackState=AttackState.Idle,e.attackTrait.currentTarget=void 0;var t=this.game.rules.general.prism.type;e.isBuilding()&&e.name===t&&this.weapon.type!==WeaponType.Secondary&&this.countSupportBeamsAndFireDownTowers(e,t),this.weapon.rules.limboLaunch&&e.attackTrait.expirePassiveScanCooldown(),(e.isInfantry()||e.isVehicle())&&(e.isFiring=!1),this.weapon.hasBurstsLeft()&&this.weapon.resetBursts()}forceCancel(t){if(t.rules.movementZone!==MovementZone.Fly)return!1;if(!this.cancellable||this.children.some(e=>!e.cancellable))return!1;if(this.status===TaskStatus.Running||this.status===TaskStatus.Cancelling){if(this.children.filter(e=>e instanceof MoveTask).some(e=>!e.forceCancel(t)))return!1;this.onEnd(t),(t.isInfantry()||t.isVehicle())&&(t.isFiring=!1)}return this.status=TaskStatus.Cancelled,!0}onTick(r){let s=r.attackTrait;(r.isInfantry()||r.isVehicle())&&s.attackState!==AttackState.Firing&&(r.isFiring=!1);let t=this.target.obj,a=this.children.find(e=>e instanceof MoveInWeaponRangeTask);if(this.isCancelling()&&s.attackState!==AttackState.FireUp)return!r.airSpawnTrait?.isLaunchingMissiles()&&(a?.cancel(),!0);let n=!1;if(s.attackState===AttackState.FireUp){if(s.isDisabled())return!0;s.attackState=AttackState.Firing,n=!0}if(s.attackState===AttackState.Firing){if(this.initialIndirectTarget&&!this.game.map.getObjectsOnTile(this.target.tile).find(e=>e.isOverlay()&&!e.isBridgePlaceholder()||e.isTerrain()))return this.cancel(),this.onTick(r);if(n){var o=this.target.obj||this.target.tile;if(!this.game.isValidTarget(this.target.obj)||this.shouldDropTarget(this.target.obj)||!this.weapon.targeting.canTarget(this.target.obj,this.target.tile,this.game,!!this.options.force,!!this.options.passive)||!this.rangeHelper.isInWeaponRange(r,o,this.weapon,this.game.rules)||!this.losHelper.hasLineOfSight(r,o,this.weapon))return s.attackState=AttackState.CheckRange,this.onTick(r)}if(this.weapon.rules.limboLaunch){if((t?.isVehicle()||t?.isAircraft())&&t.parasiteableTrait?.isInfested())return!0;if(r.rules.movementZone!==MovementZone.Fly&&t?.isUnit()&&t.zone===ZoneType.Air)return!0}if(this.target.tile.onBridgeLandType&&r.tile.onBridgeLandType&&r.isUnit()&&(this.game.map.tileOccupation.getBridgeOnTile(this.target.tile)?.isHighBridge()||this.game.map.tileOccupation.getBridgeOnTile(r.tile)?.isHighBridge()))if((t?t.isUnit()&&(t.zone===ZoneType.Air||t.onBridge):this.target.isBridge())!==(r.zone===ZoneType.Air||r.onBridge))return!0;let e=1;o=this.game.rules.general.prism.type;if(r.isBuilding()&&r.name===o&&this.weapon.type!==WeaponType.Secondary&&(o=this.countSupportBeamsAndFireDownTowers(r,o),e=1+o*this.game.rules.general.prism.supportModifier),this.weapon.rules.spawner&&(r.isVehicle()||r.isAircraft())&&r.parasiteableTrait?.isParalyzed())return!0;if(0===r.ammo)return r.isAircraft()&&(r.rules.fighter||r.rules.spawned)&&a?.cancel(),!0;let i=!1;if(this.weapon.rules.limboLaunch){let t=a;if(!t){let e=r.unitOrderTrait.getCurrentTask();if(e&&e!==this&&s.getOpportunityFireTask()===this){if(!(e instanceof MoveTask))return e.cancel(),!1;t=e}}if(t){if(!t.forceCancel(r))return!1;r.moveTrait.lastTargetOffset=void 0,r.moveTrait.lastVelocity=void 0}i=!0}return(this.weapon.fire(this.target,this.game,e),i)?!0:!!this.weapon.rules.fireOnce||(!(!this.options.passive||!r.rules.distributedFire)||(s.attackState=AttackState.JustFired,!1))}if(s.attackState===AttackState.JustFired)return s.attackState=AttackState.PrepareToFire,this.onTick(r);this.needsTargetUpdate&&(this.target=this.needsTargetUpdate,t=this.target.obj,this.needsTargetUpdate=void 0,this.onTargetChange(r),t||a?.retarget(this.target.tile,!!this.target.getBridge())),t?.isTechno()&&t.replacedBy&&(l=this.game.createTarget(t.replacedBy,t.replacedBy.tile),this.target=l,t=t.replacedBy,this.onTargetChange(r));let i=this.game.isValidTarget(t)&&!this.shouldDropTarget(t);if(i){let e=this.weapon.targeting.canTarget(t,this.target.tile,this.game,!!this.options.force,!!this.options.passive);if(!e||!r.armedTrait.isEquippedWithWeapon(this.weapon)){var l=s.selectWeaponVersus(r,this.target,this.game,this.options.force,this.options.passive);if(l){if(this.setWeapon(l),s.attackState!==AttackState.CheckRange)return s.attackState=AttackState.CheckRange,this.onTick(r);e=!0}else e=!1}i=e}if(i&&(h=this.lastTargetTpCheck,t?.isUnit()&&h&&t.moveTrait.lastTeleportTick>=h?(i=!1,this.rangeCheckCooldown=0):this.lastTargetTpCheck=this.game.currentTick),i&&t&&(this.lastValidTargetPosition={tile:t.tile,onBridge:this.target.getBridge()}),i||(this.targetLinesConfig.isAttack=!1),s.attackState===AttackState.CheckRange){if(0<this.rangeCheckCooldown)return this.rangeCheckCooldown--,!1;let e=this.target.obj?i?this.target.obj:this.lastValidTargetPosition.tile:this.target.tile;var h=this.target.obj?i?this.target.obj.isBuilding()?this.target.obj.centerTile:this.target.obj.tile:this.lastValidTargetPosition.tile:this.target.tile;if(!this.rangeHelper.isInWeaponRange(r,e,this.weapon,this.game.rules)||!this.losHelper.hasLineOfSight(r,e,this.weapon)||r.isUnit()&&r.rules.balloonHover&&!r.rules.hoverAttack&&!a&&r.tile!==h&&!this.options.holdGround||r.isAircraft()&&this.weapon.projectileRules.iniRot<=1&&!a){if(r.isUnit()&&!this.options.holdGround&&this.game.map.isWithinBounds(h)){if(a){if(a.target!==this.target.obj||i)if(i&&this.target.obj&&this.rangeHelper.tileDistance(this.target.obj,this.lastSelfMoveTargetTile)>this.weapon.range)a.retarget(this.target.obj,!!this.target.getBridge()),this.lastSelfTileBeforeMove=r.tile,this.lastSelfMoveTargetTile=this.target.obj?.tile??this.target.tile;else{if(void 0!==this.options.leashTiles&&this.rangeHelper.tileDistance(this.initialSelfPosition.tile,r.tile)>this.options.leashTiles)return a.cancel(),!0;var c=e instanceof GameObject&&e.isUnit()?e.moveTrait.baseSpeed:0,u=Math.ceil((this.rangeHelper.tileDistance(r,e)-(this.weapon.range+1))/((r.moveTrait.baseSpeed+c)/Coords.LEPTONS_PER_TILE));0<u&&(this.rangeCheckCooldown=Math.min(GameSpeed.BASE_TICKS_PER_SECOND,u))}else{let e;e=void 0!==this.options.leashTiles?this.game.createTarget(this.initialSelfPosition.onBridge,this.initialSelfPosition.tile):this.game.createTarget(this.lastValidTargetPosition.onBridge,this.lastValidTargetPosition.tile),s.currentTarget=e,a.retarget(e.tile,e.isBridge()),this.updateTargetLines(e,!1)}return!1}if(!r.moveTrait||r.moveTrait.isDisabled())return!0;if(this.isCancelling())return!0;if(r.tile===this.lastSelfTileBeforeMove||this.moveExecuted&&r.moveTrait.lastMoveResult===MoveResult.Fail?this.moveAttempts++:this.moveAttempts=0,this.weapon.rules.limboLaunch&&r.defaultToGuardArea&&t&&this.moveExecuted&&r.moveTrait.lastMoveResult===MoveResult.Fail&&this.rangeHelper.isInRange(r,t,0,r.armedTrait.computeGuardScanRange(this.weapon),!0))return!0;if(this.moveAttempts>MAX_MOVE_ATTEMPTS)return!0;0<this.moveAttempts&&this.children.push(new WaitMinutesTask(1/60));c=e,u=t&&!i?this.lastValidTargetPosition.onBridge:this.target.getBridge();return a=new MoveInWeaponRangeTask(this.game,c,!!u,this.weapon),a.blocking=!1,this.children.push(a),this.moveExecuted=!0,this.lastSelfTileBeforeMove=r.tile,this.lastSelfMoveTargetTile=c instanceof GameObject?c.tile:c,this.onTick(r)}return!0}if(this.moveExecuted=!1,this.moveAttempts=0,a&&(r.rules.balloonHover&&!r.rules.hoverAttack||r.rules.fighter||r.rules.spawned||r.rules.movementZone===MovementZone.Fly&&!this.rangeHelper.isInRange2(r,this.target.obj??this.target.tile,this.weapon.minRange,this.weapon.range-1)||a.cancel()),a&&(r.isInfantry()||this.weapon.rules.spawner))return!1;if(a?.children.some(e=>!e.cancellable)&&this.weapon.rules.limboLaunch)return!1;if(a&&a.shouldAirStrafe(r)&&this.target.obj?.isUnit()&&this.target.obj.moveTrait.isMoving()&&1<this.weapon.range&&!this.rangeHelper.isInRange2(r,this.target.obj,this.weapon.minRange,this.weapon.range-1))return!1;s.attackState=AttackState.PrepareToFire}if(s.attackState!==AttackState.PrepareToFire)return!1;if(!i||s.isDisabled())return a?.cancel(),!0;u=this.target.getWorldCoords(),c=r.position.worldPosition;if(!(this.lastInRangeTargetPosition.length()&&this.lastInRangeTargetPosition.equals(u)&&this.lastInRangeSelfPosition.length()&&this.lastInRangeSelfPosition.equals(c)))return this.lastInRangeTargetPosition.copy(u),this.lastInRangeSelfPosition.copy(c),s.attackState=AttackState.CheckRange,this.onTick(r);if(!(this.weapon.rules.omniFire||r.rules.omniFire&&r.rules.fighter)){var c=(new Vector3_Vector3).copy(u).sub(c),e=FacingUtil.fromMapCoords(new Vector2(c.x,c.z)),c=this.weapon.projectileRules.rot?FACING_DELTA_HOMING_THRESH_DEG:FACING_DELTA_NONHOMING_THRESH_DEG;if((r.isVehicle()||r.isBuilding())&&r.turretTrait){if(r.turretTrait.desiredFacing=e,Math.abs(e-r.turretTrait.facing)>=c)return!1}else if(Math.abs(e-r.direction)>=c){if(r.isAircraft())return r.direction=FacingUtil.tick(r.direction,e,r.rules.rot).facing,!1;if(a)return!1;if(this.options.disallowTurning)return!0;if(r.isVehicle())return this.children.push(new TurnTask(e)),!1;r.direction=e}}if(!this.losHelper.hasLineOfSight(r,this.target.obj||this.target.tile,this.weapon))return s.attackState=AttackState.CheckRange,this.onTick(r);if(s.isOnCooldown(r))return!1;if(this.weapon.warhead.rules.temporal&&r.temporalTrait.getTarget()===this.target.obj)return!1;if(this.weapon.rules.suicide&&this.weapon.type!==WeaponType.DeathWeapon)return this.game.destroyObject(r,{player:r.owner,obj:r,weapon:this.weapon}),!0;e=this.game.rules.general.prism.type;return r.isBuilding()&&r.name===e&&this.weapon.type!==WeaponType.Secondary&&this.fireUpPrismSupportTowers(r,e),(r.isInfantry()||r.isVehicle())&&(r.isFiring=!0),r.art.fireUp?(r.isInfantry()&&r.suppressionTrait?.isSuppressed()||this.children.push(new WaitTicksTask(r.art.fireUp).setCancellable(!1)),s.attackState=AttackState.FireUp,!1):(s.attackState=AttackState.Firing,this.onTick(r))}shouldDropTarget(e){return this.forceDropTarget||e?.isTechno()&&(this.weapon.rules.limboLaunch&&((e.isVehicle()||e.isAircraft())&&e.parasiteableTrait?.isInfested()||e.invulnerableTrait.isActive())||e.warpedOutTrait.isInvulnerable()&&!this.weapon.warhead.rules.temporal||this.initialTargetOwner!==e.owner)}fireUpPrismSupportTowers(t,i){var e;for(e of t.owner.getOwnedObjectsByType(ObjectType.Building).filter(e=>e.name===i&&e.secondaryWeapon&&!e.unitOrderTrait.hasTasks()&&e.attackTrait&&!e.attackTrait.isDisabled()&&!e.attackTrait.isOnCooldown(e)).filter(e=>this.rangeHelper.isInWeaponRange(e,t,e.secondaryWeapon,this.game.rules)).slice(0,this.game.rules.general.prism.supportMax))e.unitOrderTrait.addTask(e.attackTrait.createAttackTask(this.game,t,t.centerTile,e.secondaryWeapon,{passive:!0}))}countSupportBeamsAndFireDownTowers(t,i){var e,r=t.owner.getOwnedObjectsByType(ObjectType.Building).filter(e=>e.name===i&&e.attackTrait?.currentTarget?.obj===t);for(e of r)e.unitOrderTrait.getCurrentTask()?.cancel();return Math.min(this.game.rules.general.prism.supportMax,r.length)}getTargetLinesConfig(){return this.targetLinesConfig}}class AttackMoveTargetTask extends AttackTask{constructor(e,t,i){if(super(e,t,i),this.isAttackMove=!0,this.attackPerformed=!1,this.passedFirstWaypoint=!1,this.internalTargetUpdateRequested=!1,this.scanCooldownTicks=0,!t.obj?.isTechno())throw new Error("Target must be a techno object");this.initialTarget=t,this.initialWeapon=i,this.requestedTarget=t}duplicate(){return new AttackMoveTargetTask(this.game,this.initialTarget,this.initialWeapon)}requestTargetUpdate(e){this.internalTargetUpdateRequested?(this.requestedTarget=e,this.internalTargetUpdateRequested=!1):(this.requestedTarget===this.initialTarget?this.requestedTarget=e:this.attackPerformed=!0,this.initialTarget=e),super.requestTargetUpdate(e)}onTargetChange(e){super.onTargetChange(e);e=e.attackTrait.currentTarget;e&&e.obj!==this.initialTarget.obj&&e.obj!==this.requestedTarget.obj&&(this.requestedTarget===this.initialTarget&&(this.requestedTarget=e),this.initialTarget=e)}onTick(t){if(t.moveTrait.moveState===MoveState.Moving&&(this.passedFirstWaypoint=!0),this.scanCooldownTicks=Math.max(0,this.scanCooldownTicks-1),t.attackTrait&&!t.attackTrait.isDisabled()&&!this.isCancelling()&&(this.requestedTarget===this.initialTarget||this.attackPerformed)){if(!(t.moveTrait.isIdle()||t.tile===this.lastScanTile&&this.scanCooldownTicks)){this.lastScanTile=t.tile,this.scanCooldownTicks=this.game.rules.general.normalTargetingDelay;let e=t.attackTrait.selectDefaultWeapon(t);if(e&&(this.passedFirstWaypoint||!e.getCooldownTicks())){var i=t.attackTrait.scanForTarget(t,e,this.game);if(i.target){let{target:e,weapon:t}=i;if(!t.getCooldownTicks()){this.options.holdGround=!0,this.options.passive=!0,this.setWeapon(t);var r=this.game.createTarget(e,e.tile);return this.internalTargetUpdateRequested=!0,this.requestTargetUpdate(r),this.attackPerformed=!1}}}}if(this.attackPerformed){if(!t.isSpawned){if(!this.forceCancel(t))throw new Error("Force cancel failed");return!0}this.attackPerformed=!1,this.passedFirstWaypoint=!1,this.options.holdGround=!1,this.options.passive=!1,this.setWeapon(this.initialWeapon),this.internalTargetUpdateRequested=!0,this.requestTargetUpdate(this.initialTarget)}}r=super.onTick(t);return r&&this.requestedTarget!==this.initialTarget?(this.attackPerformed=!0,this.isCancelling()||t.attackTrait.isDisabled()):r}}class AttackMoveTask extends MoveTask{constructor(){super(...arguments),this.isAttackMove=!0,this.attackPerformed=!1,this.passedFirstWaypoint=!1}duplicate(){return new AttackMoveTask(this.game,this.targetTile,this.toBridge,this.options)}onTick(i){if(i.moveTrait.moveState===MoveState.Moving&&(this.passedFirstWaypoint=!0),i.moveTrait.moveState===MoveState.ReachedNextWaypoint&&i.attackTrait&&!i.attackTrait.isDisabled()&&(i.rules.movementZone!==MovementZone.Fly||!i.rules.balloonHover)&&(!i.ammoTrait||i.ammoTrait.ammo||!i.rules.manualReload)&&!this.isCancelling()){let e=i.attackTrait.selectDefaultWeapon(i);if(e&&(this.passedFirstWaypoint||e&&!e.getCooldownTicks())){var r=i.attackTrait.scanForTarget(i,e,this.game);if(r.target){let{target:e,weapon:t}=r;if(!t.getCooldownTicks()){r=i.attackTrait.createAttackTask(this.game,e,e.tile,t,{holdGround:!0,passive:!0});return this.children.push(r),this.useChildTargetLines=!0,this.attackPerformed=!0,i.moveTrait.velocity.set(0,0,0),i.moveTrait.currentWaypoint=void 0,i.moveTrait.collisionState=CollisionState.Waiting,!1}}}if(this.attackPerformed){if(!i.isSpawned){if(!this.forceCancel(i))throw new Error("Force cancel failed");return!0}this.attackPerformed=!1,this.passedFirstWaypoint=!1,this.useChildTargetLines=!1,i.moveTrait.collisionState=CollisionState.Resolved,this.updateTarget(this.targetTile,this.toBridge)}}return super.onTick(i)}}class ExitFactoryTask extends MoveTask{constructor(e,t,i,r){super(e,i,!1,{ignoredBlockers:[t],closeEnoughTiles:0,strictCloseEnough:!0,forceWaitOnPathBlocked:t.factoryTrait?.type!==FactoryType.InfantryType}),this.factory=t,this.rallyPoint=r,this.preventOpportunityFire=!0,this.rampBlockersPushed=!1,this.cancellable=!1}onStart(t){super.onStart(t),this.factory.factoryTrait?.type===FactoryType.UnitType&&(this.checkRampTiles=this.game.map.tileOccupation.calculateTilesForGameObject(this.factory.tile,this.factory).filter(e=>0<this.game.map.terrain.getPassableSpeed(e,t.rules.speedType,t.isInfantry(),!1)))}canStopAtTile(e,t,i){return!this.game.map.tileOccupation.isTileOccupiedBy(t,this.factory)&&super.canStopAtTile(e,t,i)}onTick(e){if(this.checkRampTiles){for(var t of this.checkRampTiles){var i,r;for(i of this.game.map.tileOccupation.getGroundObjectsOnTile(t))if(i.isUnit()){if(this.rampBlockersPushed)return!1;let e=new ScatterTask(this.game,void 0,{excludedTiles:this.checkRampTiles});e.setCancellable(!1);let t=i.unitOrderTrait.getCurrentTask();t?t.constructor!==MoveTask&&t.constructor!==AttackTask&&t.constructor!==AttackMoveTask&&t.constructor!==AttackMoveTargetTask||(r=t.duplicate(),t.cancel(),i.unitOrderTrait.addTaskNext(r),i.unitOrderTrait.addTaskNext(e)):i.unitOrderTrait.addTask(e)}}if(!this.rampBlockersPushed)return!(this.rampBlockersPushed=!0);this.checkRampTiles=void 0}return e.moveTrait.moveState===MoveState.ReachedNextWaypoint&&this.options?.ignoredBlockers&&!this.game.map.terrain.isBlockerObject(this.factory,e.tile,!1,e.rules.speedType,e.isInfantry())&&(this.options.ignoredBlockers=void 0,this.preventOpportunityFire=!1,this.rallyPoint&&(this.updateTarget(this.rallyPoint.tile,!!this.rallyPoint.onBridge),this.cancellable=!0,this.options.closeEnoughTiles=this.game.rules.general.closeEnough,this.options.strictCloseEnough=!1,this.options.forceWaitOnPathBlocked=!1)),super.onTick(e)}}class CardinalTileFinder{constructor(e,t,i,r,s,a=()=>!0){this.tiles=e,this.mapBounds=t,this.startTile=i,this.maxDistance=s,this.predicate=a,this.dirVec=new Vector2(10,0),this.finished=!1,this.diagonal=!0,this.distance=r}getNextTile(){if(!this.finished){let t;do{let e={x:this.startTile.rx,y:this.startTile.ry};e.x+=this.distance*Math.sign(this.dirVec.x),e.y+=this.distance*Math.sign(this.dirVec.y),this.dirVec.rotateAround(new Vector2,Math.PI/4*(this.diagonal?1:2)).round();var i=this.tiles.getByMapCoords(e.x,e.y);if(i&&this.mapBounds.isWithinBounds(i)&&this.predicate(i)&&(t=i),!this.dirVec.angle()){if(this.maxDistance&&this.distance>=this.maxDistance)return this.finished=!0,t;this.distance++}}while(!t);return t}}}(NotifySell=NotifySell||{}).onSell=Symbol();class DockableTrait{[NotifyUnspawn.onUnspawn](e){this.undock(e),this.reservedDock?.dockTrait.unreserveDockForUnit(e)}[NotifyOwnerChange.onChange](e){e.owner!==this.dock?.owner&&this.undock(e),e.owner!==this.reservedDock?.owner&&this.reservedDock?.dockTrait.unreserveDockForUnit(e)}[NotifyTeleport.onBeforeTeleport](e,t,i,r){r||this.undock(e)}undock(e){this.dock&&!this.dock.isDisposed&&this.dock.dockTrait.undockUnit(e)}dispose(){this.dock=void 0,this.reservedDock=void 0}}class DockTrait{constructor(e,t,i,r){this.building=e,this.tiles=t,this.numberOfDocks=i,this.dockingOffsets=r,this.ticksWhenWarpedOut=!0,this.unitsByDockNumber=new Array(i).fill(void 0),this.reservedDocks=new Array(i).fill(void 0)}[NotifySpawn.onSpawn](){this.dockTiles=[];for(let e=0;e<this.numberOfDocks;e++){var t=this.findDockTile(e);if(!t)throw new Error(`Docking tile ${e} not found for object "${this.building.name}"`);this.dockTiles[e]=t}}[NotifyUnspawn.onUnspawn](){for(let e=0;e<this.numberOfDocks;e++)this.unreserveDockAt(e)}[NotifyTick_NotifyTick.onTick](){for(let e=0;e<this.numberOfDocks;e++){var t=this.unitsByDockNumber[e];t&&t.tile!==this.getDockTile(e)&&this.undockUnit(t)}}[NotifyDestroy.onDestroy](e,t,i,r){var s=(e.rules.unitRepair||e.helipadTrait)&&!e.rules.naval&&!i?.weapon?.warhead.rules.temporal;if(s)for(var a of this.unitsByDockNumber)a&&!a.isDestroyed&&(s?t.destroyObject(a,i,r):this.undockUnit(a))}[NotifySell.onSell](r,s){if(r.helipadTrait&&this.hasDockedUnits()){var a,e,n;let t=[],i=0;for(a of[...r.owner.buildings].filter(e=>e.helipadTrait&&(e.dockTrait?.getAvailableDockCount()??!1)&&e!==r)){let e=a.dockTrait?.getAvailableDockCount()??0;for(;0<e&&i<this.unitsByDockNumber.length;)t.push(a),e--,i++;if(i===this.unitsByDockNumber.length)break}i=0;for(e of this.unitsByDockNumber)e&&((n=t[i])?e.unitOrderTrait.addTask(new MoveToDockTask(s,n)):e.unitOrderTrait.addTask(new TaskGroup(new MoveTask(s,e.tile,!1),new CallbackTask(e=>{e.crashableTrait?e.crashableTrait.crash({player:r.owner}):s.destroyObject(e,{player:r.owner})})).setCancellable(!1))),i++}else{var t,i=r.rules.unitRepair&&!r.rules.naval;for(t of this.unitsByDockNumber)t&&(i?s.sellTrait.sell(t):this.undockUnit(t))}}[NotifyOwnerChange.onChange](e,t,i){for(var r of this.unitsByDockNumber)r&&i.changeObjectOwner(r,e.owner)}getFirstAvailableDockNumber(){if(!this.building?.warpedOutTrait.isActive()){var e=this.unitsByDockNumber.findIndex((e,t)=>!e&&!this.reservedDocks[t]);if(-1!==e)return e}}getAvailableDockCount(){return this.building?.warpedOutTrait.isActive()?0:this.unitsByDockNumber.filter((e,t)=>!e&&!this.reservedDocks[t]).length}getFirstEmptyDockNumber(){if(!this.building?.warpedOutTrait.isActive()){var e=this.unitsByDockNumber.findIndex(e=>!e);if(-1!==e)return e}}getDockOffset(e){if(e>this.numberOfDocks-1)throw new RangeError(`Index ${e} exceeds available docks (${this.numberOfDocks})`);return this.dockingOffsets[e]}getDockTile(e){if(e>this.numberOfDocks-1)throw new RangeError(`Index ${e} exceeds available docks (${this.numberOfDocks})`);return this.dockTiles[e]}getDockNumberByTile(e){e=this.dockTiles.indexOf(e);if(-1!==e)return e}getAllDockTiles(){return[...this.dockTiles]}findDockTile(e){if(e>this.numberOfDocks-1)throw new RangeError(`Index ${e} exceeds available docks (${this.numberOfDocks})`);var t=this.building.position.getMapPosition(),e=this.getDockOffset(e);return this.tiles.getByMapCoords(Math.floor((t.x+e.x)/Coords.LEPTONS_PER_TILE),Math.floor((t.y+e.z)/Coords.LEPTONS_PER_TILE))}isValidUnitForDock(e){return(this.building.unitRepairTrait&&e.isVehicle()&&!this.building.helipadTrait&&(!e.rules.consideredAircraft||e.rules.landable)||e.rules.dock.includes(this.building.name)&&!(e.isAircraft()&&!this.building.helipadTrait))&&this.building.rules.naval===e.rules.naval}dockUnitAt(e,t){if(t>this.numberOfDocks-1)throw new RangeError(`Index ${t} exceeds available docks (${this.numberOfDocks})`);if(this.unitsByDockNumber[t])throw new Error("Another unit is already docked at dock #"+t);let i=e.traits.find(DockableTrait);if(!i)throw new Error(`Unit "${e.name}" cannot be docked to `+this.building.name);this.unitsByDockNumber[t]=e,i.dock=this.building}undockUnitAt(e){if(e>this.numberOfDocks-1)throw new RangeError(`Index ${e} exceeds available docks (${this.numberOfDocks})`);let t=this.unitsByDockNumber[e];t&&(this.unitsByDockNumber[e]=void 0,t.traits.get(DockableTrait).dock=void 0)}undockUnit(e){e=this.unitsByDockNumber.indexOf(e);-1!==e&&this.undockUnitAt(e)}isDocked(e){return this.unitsByDockNumber.includes(e)}hasDockedUnits(){return!!this.unitsByDockNumber.find(e=>e)}getDockedUnits(){return this.unitsByDockNumber.filter(isNotNullOrUndefined)}reserveDockAt(e,t){if(t>this.numberOfDocks-1)throw new RangeError(`Index ${t} exceeds available docks (${this.numberOfDocks})`);if(this.reservedDocks[t])throw new Error(`Dock #${t} is already reserved by `+this.reservedDocks[t].name);(this.reservedDocks[t]=e).traits.get(DockableTrait).reservedDock?.dockTrait.unreserveDockForUnit(e),e.traits.get(DockableTrait).reservedDock=this.building}unreserveDockAt(e){if(e>this.numberOfDocks-1)throw new RangeError(`Index ${e} exceeds available docks (${this.numberOfDocks})`);let t=this.reservedDocks[e];t&&(this.reservedDocks[e]=void 0,t.traits.get(DockableTrait).reservedDock=void 0)}unreserveDockForUnit(e){e=this.reservedDocks.indexOf(e);-1!==e&&this.unreserveDockAt(e)}hasReservedDockForUnit(e){return!!this.reservedDocks.includes(e)}hasReservedDockAt(e){return!!this.reservedDocks[e]}getReservedDockForUnit(e){e=this.reservedDocks.indexOf(e);if(-1!==e)return e}dispose(){this.building=void 0}}class FactoryProduceUnitEvent{constructor(e){this.target=e,this.type=EventType.FactoryProduceUnit}}!function(e){e[e.All=0]="All",e[e.Ground=1]="Ground",e[e.Air=2]="Air"}(LayerType=LayerType||{});class TileOccupation{get onChange(){return this._onChange.asEvent()}constructor(e){this.tiles=e,this.tileOccupation=[],this.emptyTiles=new Set,this._onChange=new EventDispatcher;let t=this.tileOccupation;for(var i of e.getAll())t[i.rx]=t[i.rx]||[],t[i.rx][i.ry]=new Set,this.emptyTiles.add(i)}occupyTileRange(e,t){let i=this.calculateTilesForGameObject(e,t);i.forEach(e=>this.occupyTile(e,t)),this._onChange.dispatch(this,{tiles:i,object:t,type:"added"})}unoccupyTileRange(e,t){let i=this.calculateTilesForGameObject(e,t);i.forEach(e=>this.unoccupyTile(e,t)),this._onChange.dispatch(this,{tiles:i,object:t,type:"removed"})}occupySingleTile(e,t){this.occupyTile(e,t),this._onChange.dispatch(this,{tiles:[e],object:t,type:"added"})}unoccupySingleTile(e,t){this.unoccupyTile(e,t),this._onChange.dispatch(this,{tiles:[e],object:t,type:"removed"})}calculateTilesForGameObject(e,t){return this.tiles.getInRectangle(e,t.getFoundation())}occupyTile(e,t){let i=this.tileOccupation[e.rx]?.[e.ry];i&&(i.add(t),this.emptyTiles.delete(e),e.landType=this.computeTileLandType(e),e.onBridgeLandType=this.computeOnBridgeLandType(e))}unoccupyTile(e,t){let i=this.tileOccupation[e.rx]?.[e.ry];i&&(i.delete(t),i.size||this.emptyTiles.add(e),e.landType=this.computeTileLandType(e),e.onBridgeLandType=this.computeOnBridgeLandType(e))}isTileOccupiedBy(e,t){return!!this.tileOccupation[e.rx]?.[e.ry]?.has(t)}computeTileLandType(e){if(e.landType===LandType.Rock)return LandType.Rock;var t,i=getLandType(e.terrainType);for(t of this.tileOccupation[e.rx]?.[e.ry]??[]){if(t.isBuilding()&&t.rules.wall)return LandType.Wall;if(t.isOverlay()&&!t.isBridge()&&!t.isBridgePlaceholder())if(t.getLandType()!==LandType.Clear)return t.getLandType()}return i}computeOnBridgeLandType(e){for(var t of this.tileOccupation[e.rx]?.[e.ry]??[])if(t.isOverlay()&&t.isBridge())return t.getLandType()}getTileZone(e,t=!1){return getZoneType(t?e.landType:e.onBridgeLandType??e.landType)}getBridgeOnTile(e){for(var t of this.tileOccupation[e.rx]?.[e.ry]??[])if(t.isOverlay()&&t.isBridge())return t}getObjectsOnTile(e){return[...this.tileOccupation[e.rx]?.[e.ry]??[]]}getGroundObjectsOnTile(e){let t=[];for(var i of this.tileOccupation[e.rx]?.[e.ry]??[])i.isTechno()&&!i.isBuilding()&&i.zone===ZoneType.Air||t.push(i);return t}getAirObjectsOnTile(e){let t=[];for(var i of this.tileOccupation[e.rx]?.[e.ry]??[])i.isUnit()&&i.zone===ZoneType.Air&&t.push(i);return t}getObjectsOnTileByLayer(e,t){if(t===LayerType.Ground)return this.getGroundObjectsOnTile(e);if(t===LayerType.Air)return this.getAirObjectsOnTile(e);if(t===LayerType.All)return this.getObjectsOnTile(e);throw new Error(`Unhandled layer type "${t}"`)}getEmptyTiles(){return[...this.emptyTiles]}}(NotifyWarpChange_NotifyWarpChange=NotifyWarpChange_NotifyWarpChange||{}).onChange=Symbol(),(NotifyProduceUnit=NotifyProduceUnit||{}).onProduce=Symbol(),function(e){e[e.Idle=0]="Idle",e[e.Delivering=1]="Delivering"}(FactoryStatus=FactoryStatus||{});class FactoryTrait{constructor(e,t=!1){this.type=e,this.isCloningVats=t,this.status=FactoryStatus.Idle}[NotifySpawn.onSpawn](e,t){this.resetRallyPoint(e,t)}resetRallyPoint(e,t){var i;[FactoryType.BuildingType,FactoryType.AircraftType].includes(this.type)||(i=this.computeDefaultRallyPoint(e,this.type,t.map),e.rallyTrait?.changeRallyPoint(i,e,t))}[NotifyWarpChange_NotifyWarpChange.onChange](t,e,i){if(t.owner.production){let e=[];e=this.type===FactoryType.BuildingType?[QueueType.Structures,QueueType.Armory]:[t.owner.production.getQueueTypeForFactory(this.type)];for(var r of e)t.owner.production.getQueue(r).notifyUpdated()}}[NotifyOwnerChange.onChange](e,t,i){this.status===FactoryStatus.Delivering&&e.rules.deployTime&&this.deliveringUnit&&!this.deliveringUnit.isDestroyed&&this.unitIsInsideFactory(this.deliveringUnit,e,i)&&i.changeObjectOwner(this.deliveringUnit,e.owner)}[NotifyDestroy.onDestroy](e,t,i,r){this.status===FactoryStatus.Delivering&&e.rules.deployTime&&this.deliveringUnit&&!this.deliveringUnit.isDestroyed&&e.deathType!==DeathType.Temporal&&this.unitIsInsideFactory(this.deliveringUnit,e,t)&&t.destroyObject(this.deliveringUnit,i,r)}[NotifyTick_NotifyTick.onTick](i,r){if(this.status===FactoryStatus.Delivering){if(!this.deliveringUnit||this.deliveringUnit.isDestroyed){if(this.buildingProductionTicks=this.buildingProductionTicks??1,0<this.buildingProductionTicks--)return;this.buildingProductionTicks=void 0}else if(!this.unitHasClearedFactory(this.deliveringUnit,i,r))return;return this.status=FactoryStatus.Idle,void(this.deliveringUnit=void 0)}if(i.owner.production&&!i.warpedOutTrait.isActive()){let e=i.owner.production.getPrimaryFactory(this.type);if((e?.warpedOutTrait.isActive()||e===i||e?.factoryTrait?.deliveringUnit&&e.factoryTrait.type===FactoryType.UnitType)&&this.type!==FactoryType.BuildingType){let e=i.owner.production.getQueueForFactory(this.type);if(e&&e.status===QueueStatus.Ready){let t=e.getFirst();if(this.type===FactoryType.AircraftType){let e=this.produceAircraftAt(i,t,r);var s;if(!e)for(s of[...i.owner.buildings].filter(e=>e.factoryTrait?.type===FactoryType.AircraftType&&e.helipadTrait)){if(e)break;e=this.produceAircraftAt(s,t,r)}if(!e)return}else{var a;if(this.produceGroundUnitAt(i,t,r),!this.isCloningVats&&this.type===FactoryType.InfantryType)for(a of[...i.owner.buildings].filter(e=>e.factoryTrait&&e.rules.cloning))a.factoryTrait.status===FactoryStatus.Idle&&a.factoryTrait.produceGroundUnitAt(a,t,r)}i.owner.addUnitsBuilt(t.rules,1),t.creditsSpent=0,t.progress=0,e.shift(t.rules,1),e.currentSize&&(e.status=QueueStatus.Active)}}}}unitIsInsideFactory(e,t,i){return i.map.tileOccupation.isTileOccupiedBy(e.tile,t)&&e.zone!==ZoneType.Air}unitHasClearedFactory(e,t,i){return!i.map.tileOccupation.isTileOccupiedBy(e.tile,t)||e.rules.consideredAircraft&&e.position.tileElevation>=t.art.height}produceGroundUnitAt(t,e,i){let r=i.createUnitForPlayer(e.rules,t.owner);e.rules.trainable&&t.owner.canProduceVeteran(r.rules)&&r.veteranTrait?.setVeteranLevel(VeteranLevel.Veteran),r.isInfantry()&&(r.position.subCell=Infantry_Infantry.SUB_CELLS[0]);let s=this.computeInternalRallyPoint(t,this.type,t.rallyTrait.getRallyPoint(),i.map);this.type!==FactoryType.UnitType&&(s=t.rallyTrait.findRallyPointforUnit(r,s,i.map,!1,t.tile.z));let a;a=this.type===FactoryType.NavalUnitType?s:(e=this.computeExitCoords(t,this.type),i.map.tiles.getByMapCoords(Math.floor(e.rx),Math.floor(e.ry))),r.rules.consideredAircraft&&(s=a);let n;if(t.rallyTrait.getRallyPoint()!==s&&(n=t.rallyTrait.findRallyNodeForUnit(r,i.map)),r.isInfantry()){let t=i.map.tileOccupation.getObjectsOnTileByLayer(n?.tile??s,r.rules.consideredAircraft?LayerType.Air:LayerType.Ground).filter(e=>e.isInfantry()&&e.moveTrait.moveState!==MoveState.Moving).map(e=>e.position.subCell);r.position.subCell=Infantry_Infantry.SUB_CELLS.find(e=>!t.includes(e))??Infantry_Infantry.SUB_CELLS[0]}function o(){var e;r.rules.consideredAircraft?(e=n??{tile:s,onBridge:void 0},r.unitOrderTrait.addTaskNext(new MoveTask(i,e.tile,!!e.onBridge,{closeEnoughTiles:i.rules.general.closeEnough}))):r.unitOrderTrait.addTaskNext(new ExitFactoryTask(i,t,s,n))}r.direction=270,i.spawnObject(r,a),i.traits.filter(NotifyProduceUnit).forEach(e=>{e[NotifyProduceUnit.onProduce](r,i)}),i.events.dispatch(new FactoryProduceUnitEvent(r)),t.rules.deployTime?r.unitOrderTrait.addTask(new TaskGroup(new WaitMinutesTask(t.rules.deployTime),new CallbackTask(()=>{t.isSpawned&&t.buildStatus!==BuildStatus.BuildDown&&o()})).setCancellable(!1)):o(),this.status=FactoryStatus.Delivering,this.deliveringUnit=r}produceAircraftAt(e,t,i){let r=e.traits.find(DockTrait);if(!r)return!1;var s=r.getFirstAvailableDockNumber();if(void 0===s)return!1;let a=i.createUnitForPlayer(t.rules,e.owner);t.rules.trainable&&e.owner.canProduceVeteran(a.rules)&&a.veteranTrait?.setVeteranLevel(VeteranLevel.Veteran);t=r.getDockOffset(s);return a.position.moveToLeptons(e.position.getMapPosition()),a.position.moveByLeptons3(t),i.spawnObject(a,a.position.tile),r.dockUnitAt(a,s),a.isAircraft()&&a.airportBoundTrait&&(a.airportBoundTrait.preferredAirport=e),i.traits.filter(NotifyProduceUnit).forEach(e=>{e[NotifyProduceUnit.onProduce](a,i)}),i.events.dispatch(new FactoryProduceUnitEvent(a)),!0}computeExitCoords(e,t){if(t===FactoryType.InfantryType)return this.computeBarracksDefaultExitCoords(e);if(t===FactoryType.UnitType)return this.computeWarFactoryExitCoords(e);throw new Error("Unsupported factory type "+FactoryType[t])}computeInternalRallyPoint(e,t,i,r){let s,a;if(t===FactoryType.NavalUnitType)a=this.computeNavalInternalRallyPoint(e,i,r);else{if(t===FactoryType.InfantryType)s=this.computeBarracksInternalRallyCoords(e);else{if(t!==FactoryType.UnitType)throw new Error("Unsupported factory type "+FactoryType[t]);s=this.computeWarFactoryInternalRallyCoords(e)}a=r.tiles.getByMapCoords(s.rx,s.ry)}return a??this.findTileAdjacentToBuilding(e,r)}computeDefaultRallyPoint(e,t,i){let r,s;if(t===FactoryType.NavalUnitType)s=this.computeNavalDefaultRallyPoint(e,i);else{if(t===FactoryType.InfantryType)r=this.computeBarracksInternalRallyCoords(e);else{if(t!==FactoryType.UnitType)throw new Error("Unsupported factory type "+FactoryType[t]);r=this.computeWarFactoryDefaultRallyCoords(e)}s=i.tiles.getByMapCoords(r.rx,r.ry)}return s??this.findTileAdjacentToBuilding(e,i)}findTileAdjacentToBuilding(e,t){return new RadialTileFinder(t.tiles,t.mapBounds,e.tile,e.getFoundation(),1,1,()=>!0).getNextTile()}computeBarracksDefaultExitCoords(e){var t=e.getFoundation();let i,r;return t.width<=2||t.height<=2?(i=t.width-1,r=t.height-1,e.rules.gdiBarracks&&2<t.width&&(i=Math.floor(t.width/2))):(i=0,r=t.height-1),{rx:e.tile.rx+i,ry:e.tile.ry+r}}computeBarracksInternalRallyCoords(e){var t=e.getFoundation();let{rx:i,ry:r}=this.computeBarracksDefaultExitCoords(e);return!(t.width<=2||t.height<=2)||e.rules.gdiBarracks?r+=1:e.rules.nodBarracks&&(i+=t.width<=2?1:0,r+=t.height<=2?1:0),{rx:i,ry:r}}computeWarFactoryExitCoords(e){var t=e.getFoundation();return{rx:e.tile.rx+Math.floor(t.width/2),ry:e.tile.ry+Math.floor(t.height/2)}}computeWarFactoryInternalRallyCoords(e){var t=e.getFoundation();return{rx:e.tile.rx+t.width-1,ry:e.tile.ry+Math.floor(t.height/2)}}computeWarFactoryDefaultRallyCoords(e){var t=e.getFoundation();return{rx:e.tile.rx+t.width,ry:e.tile.ry+Math.floor(t.height/2)}}computeNavalDefaultRallyPoint(e,t){let i=new CardinalTileFinder(t.tiles,t.mapBounds,e.centerTile,5,5,e=>e.terrainType===TerrainType.Water&&!t.getObjectsOnTile(e).find(e=>e.isBuilding()||e.isOverlay()&&e.isBridge()));return i.diagonal=!1,i.getNextTile()??t.tiles.getByMapCoords(e.tile.rx+e.getFoundation().width,e.tile.ry+e.getFoundation().height)}computeNavalInternalRallyPoint(e,t,i){t=new Vector2(t.rx,t.ry).sub(new Vector2(e.centerTile.rx,e.centerTile.ry));return i.tiles.getByMapCoords(e.centerTile.rx+Math.sign(t.x)*(Math.floor(e.getFoundation().width/2)+1),e.centerTile.ry+Math.sign(t.y)*(Math.floor(e.getFoundation().height/2)+1))}}(NotifyBuildStatus=NotifyBuildStatus||{}).onStatusChange=Symbol();class RadialBackFirstTileFinder{constructor(e,t,i,r,s,a,n,o=!0){this.tiles=e,this.mapBounds=t,this.startTile=i,this.foundation=r,this.maxDistance=a,this.predicate=n,this.checkBounds=o,this.distance=s,this.generator=this.generate()}getNextTile(){return this.generator.next().value}*generate(){var r=(e,t)=>{t=this.tiles.getByMapCoords(e,t);if(t&&(!this.checkBounds||this.mapBounds.isWithinBounds(t))&&this.predicate(t))return t};do{var s=this.startTile.rx-this.distance,a=this.startTile.ry-this.distance,n=this.startTile.rx+this.foundation.width-1+this.distance,o=this.startTile.ry+this.foundation.height-1+this.distance;let e,t,i;if(0<this.distance){for(t=1+a;t<o;t++)i=r(s,t),i&&(yield i);for(e=s;e<n;e++)i=r(e,a),i&&(yield i);for(t=o-1;t>=a;t--)i=r(n,t),i&&(yield i);for(e=n;e>=s;e--)i=r(e,o),i&&(yield i)}else this.predicate(this.startTile)&&(yield this.startTile)}while(this.distance++,this.distance<=this.maxDistance)}}class FreeUnitTrait{[NotifyBuildStatus.onStatusChange](t,s,a){if(s.buildStatus===BuildStatus.Ready&&t===BuildStatus.BuildUp&&!s.owner.isNeutral){let e;if(a.rules.hasObject(s.rules.freeUnit,ObjectType.Vehicle))e=a.rules.getObject(s.rules.freeUnit,ObjectType.Vehicle);else{if(!a.rules.hasObject(s.rules.freeUnit,ObjectType.Infantry))return void console.warn(`Free unit "${s.rules.freeUnit}" is not a vehicle or infantry type.`);e=a.rules.getObject(s.rules.freeUnit,ObjectType.Infantry)}let i=a.createUnitForPlayer(e,s.owner),r;t=new RadialBackFirstTileFinder(a.map.tiles,a.map.mapBounds,s.tile,s.getFoundation(),1,1,e=>{var t=0<a.map.terrain.getPassableSpeed(e,i.rules.speedType,i.isInfantry(),!1)&&Math.abs(e.z-s.tile.z)<2&&!a.map.terrain.findObstacles({tile:e,onBridge:void 0},i).length;return!r&&t&&(r=e),t&&!a.map.getObjectsOnTile(e).find(e=>e.isOverlay())}).getNextTile()??r;if(!t)return s.owner.removeOwnedObject(i),i.dispose(),void(s.owner.credits+=i.purchaseValue);a.spawnObject(i,t)}}}class CrewedTrait{[NotifySell.onSell](e,t){this.spawnSurvivors(e,t)}[NotifyDestroy.onDestroy](e,t,i,r){r||i?.obj===e&&i.weapon?.rules.suicide||e.isVehicle()&&e.moveTrait.isMoving()||e.crashableTrait||this.spawnSurvivors(e,t)}spawnSurvivors(r,s){var e=s.rules.general.crew,t=r.owner.country.side;let i,a;if(t===SideType.GDI)i=e.alliedSurvivorDivisor,a=e.alliedCrew;else if(t===SideType.Nod)i=e.sovietSurvivorDivisor,a=e.sovietCrew;else{if(t!==SideType.ThirdSide)return;i=e.thirdSurvivorDivisor,a=e.thirdCrew}let n=s.sellTrait.computeRefundValue(r)/i;n=0<n&&n<1?1:Math.floor(n),n=r.isVehicle()?Math.min(1,n):Math.min(5,n);let o=[];for(let e=0;e<n;e++)o.push(a);if(0<o.length){r.rules.constructionYard&&(o[o.length-1]=s.rules.general.engineer);var l,h=s.map.tiles.getInRectangle(r.tile,r.getFoundation()).filter(e=>s.map.isWithinBounds(e));let i=[...h];for(l of o){var c=s.rules.getObject(l,ObjectType.Infantry);if(s.map.terrain.getPassableSpeed(r.tile,c.speedType,!0,!r.isBuilding()&&r.onBridge,void 0,!0)){let e=s.createUnitForPlayer(c,r.owner),t=i.length?i.splice(s.generateRandomInt(0,i.length-1),1)[0]:void 0;t=t||h[s.generateRandomInt(0,h.length-1)],e.isInfantry()&&(e.position.subCell=Infantry_Infantry.SUB_CELLS[0]),e.veteranTrait&&r.owner.canProduceVeteran(e.rules)&&e.veteranTrait.setVeteranLevel(VeteranLevel.Veteran),s.spawnObject(e,t),r.isBuilding()&&e.unitOrderTrait.addTask(new ScatterTask(s,void 0,{ignoredBlockers:r.isDestroyed?void 0:[r]}))}}}}}class CabHutTrait{constructor(e,t){this.gameObject=e,this.bridges=t,this.checkedClosestBridge=!1}canRepairBridge(){var e=this.findClosestBridgeBounds();return e?this.bridges.canBeRepaired(e):(console.warn(`No bridge associated with hut at ${this.gameObject.tile.rx}, ${this.gameObject.tile.ry}.`),!1)}repairBridge(t,i){var r=this.findClosestBridgeBounds();if(!r)throw new Error("No bridge bounds found");var e=this.bridges.findDestroyedPieceTiles(r),s=r.start.rx!==r.end.rx;let a;a=r.isHigh?BridgeOverlayTypes.calculateHighBridgeOverlayId(r.type,s):BridgeOverlayTypes.calculateLowBridgeOverlayId(r.type,s);var n,o,l=t.rules.getOverlayName(a);for(n of e){let e=t.createObject(ObjectType.Overlay,l);e.overlayId=a,e.value=0,e.position.tileElevation=r.isHigh?4:0,t.spawnObject(e,n),this.updateUnitsUnderBridgePiece(n,r,t,i)}for(o of this.bridges.findBridgePieces(r))o.obj.bridgeTrait.bridgeSpec=r}updateUnitsUnderBridgePiece(e,i,r,s){var a;for(let t of this.bridges.getPieceTiles(this.bridges.getPieceAtTile(e)))if(i.isHigh){let e=r.map.getGroundObjectsOnTile(t).filter(e=>e.tile===t&&e.isUnit()&&!e.unitOrderTrait.hasTasks()&&e.rules.tooBigToFitUnderBridge);e.forEach(e=>e.unitOrderTrait.addTask(new ScatterTask(r)))}else for(a of r.map.getGroundObjectsOnTile(t))a.isUnit()&&(r.map.terrain.getPassableSpeed(t,a.rules.speedType,a.isInfantry(),!0)?(a.zone=ZoneType.Ground,a.onBridge=!0):a.isDestroyed||r.destroyObject(a,{player:s}))}demolishBridge(e,t){var i=this.getBridgePieces();if(i)for(var r of i)r.obj.isLowBridge()&&e.map.getTileZone(r.obj.tile,!0)!==ZoneType.Water||r.obj.isDestroyed||(r.obj.deathType=DeathType.Demolish,e.destroyObject(r.obj,t,!0))}getBridgePieces(){var e=this.findClosestBridgeBounds();if(e)return this.bridges.findBridgePieces(e)}findClosestBridgeBounds(){return this.checkedClosestBridge||(this.checkedClosestBridge=!0,this.closestBridge=this.bridges.findClosestBridgeSpec(this.gameObject.tile)),this.closestBridge}dispose(){this.gameObject=void 0}}class OilDerrickTrait{constructor(){this.isActive=!1,this.produceCashCooldown=0}[NotifySpawn.onSpawn](e){e.owner.isNeutral||(this.isActive=!0)}[NotifyOwnerChange.onChange](e,t){t.isNeutral&&!e.owner.isNeutral&&(e.owner.credits=Math.max(0,e.owner.credits+e.rules.produceCashStartup),0<e.rules.produceCashStartup&&(e.owner.creditsGained+=e.rules.produceCashStartup),this.isActive=!0,this.produceCashCooldown=e.rules.produceCashDelay)}[NotifyTick_NotifyTick.onTick](e){this.isActive&&(this.produceCashCooldown--,this.produceCashCooldown<=0&&(this.produceCashCooldown=e.rules.produceCashDelay,e.owner.credits=Math.max(0,e.owner.credits+e.rules.produceCashAmount),0<e.rules.produceCashAmount&&(e.owner.creditsGained+=e.rules.produceCashAmount)))}}const wallTypes=[[0,0,0,0],[1,0,0,0],[0,1,0,0],[1,1,0,0],[0,0,1,0],[1,0,1,0],[0,1,1,0],[1,1,1,0],[0,0,0,1],[1,0,0,1],[0,1,0,1],[1,1,0,1],[0,0,1,1],[1,0,1,1],[0,1,1,1],[1,1,1,1]];class WallTrait{constructor(){this.linkedDamageHandled=!1,this.wallType=0}[NotifySpawn.onSpawn](e,t){e.isBuilding()?this.connectWall(e,t.map):this.wallType=e.value}[NotifyUnspawn.onUnspawn](e,t){this.updateAdjacentWalls(e,t.map)}[NotifyDamage.onDamage](e,t,i,r){if(!this.linkedDamageHandled){var s=Math.floor(i/2);if(s)for(var a of t.map.tiles.getAllNeighbourTiles(e.tile))if(a.landType===LandType.Wall){let e=t.map.getObjectsOnTile(a).find(e=>(e.isBuilding()||e.isOverlay())&&e.wallTrait);e.wallTrait.linkedDamageHandled=!0,e.healthTrait.inflictDamage(s,r,t),e.wallTrait.linkedDamageHandled=!1,e.healthTrait.health||t.destroyObject(e,r)}}}updateAdjacentWalls(t,e){let i=new CardinalTileFinder(e.tiles,e.mapBounds,t.tile,1,1);for(i.diagonal=!1;r=i.getNextTile();){var r=e.getObjectsOnTile(r).find(e=>(e.isBuilding()||e.isOverlay())&&e.name===t.rules.name);r&&this.connectWall(r,e)}}connectWall(e,i){let t=this.getAdjacentWallData(e.tile,e.name,i);this.updateWallType(e,t.map(e=>e.direction)),t.forEach(e=>{let t=this.getAdjacentWallData(e.tile,e.wall.name,i);this.updateWallType(e.wall,t.map(e=>e.direction))})}updateWallType(e,t){let i=[0,0,0,0];for(var r of t)0===r[0]&&-1===r[1]&&(i[0]=1),1===r[0]&&0===r[1]&&(i[1]=1),0===r[0]&&1===r[1]&&(i[2]=1),-1===r[0]&&0===r[1]&&(i[3]=1);t=this.findWallType(i);e.wallTrait.wallType=t,e.isOverlay()&&(e.value=t)}findWallType(t){for(let e=0;e<wallTypes.length;++e){var i=wallTypes[e];if(i[0]===t[0]&&i[1]===t[1]&&i[2]===t[2]&&i[3]===t[3])return e}return console.warn("Invalid wall directions",t),0}getAdjacentWallData(e,t,i){var r;let s=[];for(r of[[0,1],[0,-1],[1,0],[-1,0]]){var a={x:e.rx+r[0],y:e.ry+r[1]},n=i.tiles.getByMapCoords(a.x,a.y);n&&((a=i.getObjectsOnTile(n).find(e=>(e.isBuilding()||e.isOverlay())&&e.name===t))&&s.push({direction:r,tile:n,wall:a}))}return s}}const CHARGERS_TO_POWER_ON=2,CHARGERS_TO_OVERPOWER=1;class OverpoweredTrait{constructor(e){this.obj=e,this.chargers=new Set}isOverpowered(){let e=CHARGERS_TO_OVERPOWER;return this.obj?.poweredTrait?.isPoweredOn(!0)||(e+=CHARGERS_TO_POWER_ON),this.chargers.size>=e}hasChargersToPowerOn(){return this.chargers.size>=CHARGERS_TO_POWER_ON}chargeFrom(e){this.chargers.add(e),this.swapAttackTaskWeapon()}[NotifyTick_NotifyTick.onTick](i){if(0<this.chargers.size){let t=!1;this.chargers.forEach(e=>{(e.isDestroyed||e.isCrashing||e.owner!==i.owner||e.attackTrait?.currentTarget?.obj!==i)&&(this.chargers.delete(e),t=!0)}),t&&this.swapAttackTaskWeapon()}}swapAttackTaskWeapon(){let e=this.obj?.unitOrderTrait.getCurrentTask();var t;e instanceof AttackTask&&((t=this.getWeapon())?e.setWeapon(t):e.cancel())}getWeapon(){return this.isOverpowered()?this.obj?.secondaryWeapon:this.obj?.primaryWeapon}dispose(){this.obj=void 0,this.chargers.clear()}}class UnitRepairFinishEvent{constructor(e,t){this.target=e,this.from=t,this.type=EventType.UnitRepairFinish}}class UnitRepairStartEvent{constructor(e){this.target=e,this.type=EventType.UnitRepairStart}}!function(e){e[e.Idle=0]="Idle",e[e.Repairing=1]="Repairing"}(RepairStatus=RepairStatus||{});class UnitRepairTrait{constructor(){this.status=RepairStatus.Idle,this.cooldownTicks=0,this.lastRepairTickSuccessful=!1}[NotifySpawn.onSpawn](e,t){this.resetRallyPoint(e,t)}resetRallyPoint(e,t){var i;e.factoryTrait||(i=this.computeDefaultRallyPoint(e,t.map),e.rallyTrait.changeRallyPoint(i,e,t))}[NotifyTick_NotifyTick.onTick](t,i){if(t.dockTrait&&(!t.rules.needsEngineer||!t.owner.isNeutral))if(!t.dockTrait.hasDockedUnits()||t.dockTrait.getDockedUnits().some(e=>e.zone===ZoneType.Air)||t.poweredTrait&&!t.poweredTrait.isPoweredOn())this.status=RepairStatus.Idle;else if(this.cooldownTicks<=0){var r,s,a=i.rules.general.repair,a=t.rules.unitReload?a.reloadRate:a.uRepairRate;this.cooldownTicks+=GameSpeed.BASE_TICKS_PER_SECOND*a*60;let e=!1;for(r of t.dockTrait.getDockedUnits())r.zone!==ZoneType.Air&&(r.healthTrait.health<100&&i.areFriendly(r,t)?(this.tickRepair(r,i,t)&&(e=!0),!e||this.status!==RepairStatus.Idle&&this.lastRepairTickSuccessful||t.helipadTrait||i.events.dispatch(new UnitRepairStartEvent(r))):((s=t.rallyTrait.findRallyNodeForUnit(r,i.map))&&(t.dockTrait.undockUnit(r),r.unitOrderTrait.addTask(new MoveTask(i,s.tile,!!s.onBridge,{closeEnoughTiles:i.rules.general.closeEnough}))),t.helipadTrait||i.events.dispatch(new UnitRepairFinishEvent(r,t))));this.lastRepairTickSuccessful=e,this.status=e?RepairStatus.Repairing:RepairStatus.Idle}else this.cooldownTicks--}tickRepair(e,t,i){var r=t.rules.general.repair,s=Math.floor(r.repairStep),a=r.repairPercent;let n;if(a){r=a*e.purchaseValue/e.healthTrait.maxHitPoints,a=Math.min(i.owner.credits,Math.max(1,Math.floor(r*s)));if(n=r&&a?Math.floor(a/r):s,!a)return!1;i.owner.credits-=a}else n=s;return n=Math.min(n,e.healthTrait.maxHitPoints-e.healthTrait.getHitPoints()),!!n&&(e.healthTrait.healBy(n,i,t),!0)}computeDefaultRallyPoint(e,t){var i=e.getFoundation(),i=new Vector2(e.tile.rx,e.tile.ry+i.height);return t.tiles.getByMapCoords(i.x,i.y)??e.tile}}class RallyTrait{getRallyPoint(){return this.rallyPoint}changeRallyPoint(e,t,i){i=this.findValidRallyPoint(t,e,i.map);i&&(this.rallyPoint=i)}findValidRallyPoint(i,e,r){let t=new RadialTileFinder(r.tiles,r.mapBounds,e,{width:1,height:1},0,20,e=>(i.rules.naval||e.terrainType!==TerrainType.Water)&&!r.tileOccupation.isTileOccupiedBy(e,i)),s=t.getNextTile();if(!s&&i.factoryTrait?.type===FactoryType.NavalUnitType){var{width:a,height:n}=i.getFoundation();for(let t=0;t<a;t++)for(let e=0;e<n;e++){var o=r.tiles.getByMapCoords(i.tile.rx+t,i.tile.ry+e);if(!o)break;if(0<r.terrain.getPassableSpeed(o,SpeedType.Float,!1,!1)){s=o;break}}}return s}findRallyNodeForUnit(e,t){if(this.rallyPoint){var i=this.findRallyPointforUnit(e,this.rallyPoint,t,!0);return{tile:i,onBridge:e.rules.naval?void 0:t.tileOccupation.getBridgeOnTile(i)}}}findRallyPointforUnit(i,e,r,s,a){let n=i.rules.naval?void 0:r.tileOccupation.getBridgeOnTile(e),o=i.rules.movementZone===MovementZone.Fly,t=new RadialTileFinder(r.tiles,r.mapBounds,e,{width:1,height:1},0,5,e=>{var t=!n||n.isHighBridge()?r.tileOccupation.getBridgeOnTile(e):void 0;return!(o?[]:r.terrain.findObstacles({tile:e,onBridge:t},i)).length&&(void 0===a||Math.abs(a-(e.z+(t?.tileElevation??0)))<4)&&(!s||!r.getObjectsOnTile(e).find(e=>e.isBuilding()&&!e.isDestroyed))&&(o||0<r.terrain.getPassableSpeed(e,i.rules.speedType,i.isInfantry(),!!t))});return t.getNextTile()??e}}class Timer{constructor(){this.activeTicks=0}isActive(){return 0<this.activeTicks}setActiveFor(e,t){this.activeTicks=e,this.activeFor=e,this.activeSince=t}reset(){this.activeTicks=0,this.activeSince=void 0,this.activeFor=void 0}getTicksLeft(){return this.activeTicks}getInitialTicks(){return this.activeFor??0}tick(e){return 0<this.activeTicks&&(this.activeTicks--,this.activeTicks<=0||void 0!==this.activeSince&&e-this.activeSince>this.activeFor)&&(this.reset(),!0)}}class C4ChargeTrait{constructor(){this.timer=new Timer}hasCharge(){return this.timer.isActive()}setCharge(e,t){this.hasCharge()||(this.timer.setActiveFor(e),this.attackerInfo=t)}[NotifyTick_NotifyTick.onTick](e,t){this.timer.isActive()&&!0===this.timer.tick(t.currentTick)&&(e.invulnerableTrait.isActive()||(e.isBuilding()&&e.cabHutTrait?e.cabHutTrait.demolishBridge(t,this.attackerInfo):(e.deathType=DeathType.Demolish,t.destroyObject(e,this.attackerInfo,!0))))}}class HelipadTrait{[NotifyOwnerChange.onChange](e,t,i){this.checkAircraftsForPlayer(t,i)}[NotifyUnspawn.onUnspawn](e,t){this.checkAircraftsForPlayer(e.owner,t)}checkAircraftsForPlayer(e,t){let i=t.rules.general.padAircraft;var r;for(r of e.getOwnedObjectsByType(ObjectType.Aircraft).filter(e=>i.includes(e.name)))r.airportBoundTrait&&(r.airportBoundTrait.preferredAirport=void 0)}}class UnitReloadTrait{[NotifyTick_NotifyTick.onTick](t,i){if(t.dockTrait&&t.dockTrait.hasDockedUnits()&&!t.dockTrait.getDockedUnits().every(e=>!this.canReloadUnit(e)))if(void 0===this.cooldownTicks&&(this.cooldownTicks=GameSpeed.BASE_TICKS_PER_SECOND*i.rules.general.repair.reloadRate*60),this.cooldownTicks<=0){this.cooldownTicks=GameSpeed.BASE_TICKS_PER_SECOND*i.rules.general.repair.reloadRate*60;let e=t.dockTrait.getDockedUnits();var r;for(r of 0===e[0].ammo?e.slice(0,1):e)this.canReloadUnit(r)&&r.ammoTrait.ammo++}else this.cooldownTicks--}canReloadUnit(e){return!(!e.ammoTrait||!e.rules.manualReload||e.ammoTrait.isFull()||e.zone===ZoneType.Air)}}class WaitForBuildUpTask extends TaskGroup{constructor(e,t){super(new WaitMinutesTask(e),new CallbackTask(e=>e.setBuildStatus(BuildStatus.Ready,t))),this.cancellable=!1}}class SuperWeaponTrait{constructor(e){this.name=e}getSuperWeapon(e){return e.owner.superWeaponsTrait?.get(this.name)}[NotifySpawn.onSpawn](e,t){this.addSuperWeaponToPlayerIfNeeded(e.owner,t)}[NotifyUnspawn.onUnspawn](e,t){this.removeSuperWeaponFromPlayerIfNeeded(e.owner)}[NotifyOwnerChange.onChange](e,t,i){this.removeSuperWeaponFromPlayerIfNeeded(t),this.addSuperWeaponToPlayerIfNeeded(e.owner,i)}addSuperWeaponToPlayerIfNeeded(t,i){if(t.superWeaponsTrait&&!t.superWeaponsTrait.has(this.name)){let e=i.createSuperWeapon(this.name,t);t.superWeaponsTrait.add(e),e.rules.isPowered&&t.powerTrait?.isLowPower()&&e.pauseTimer()}}removeSuperWeaponFromPlayerIfNeeded(e){let t=e.superWeaponsTrait;t&&(e.getOwnedObjectsByType(ObjectType.Building).some(e=>e.superWeaponTrait?.name===this.name)||(e=t.get(this.name))&&!e.isGift&&t.remove(this.name))}}const TEMPORARY_REVEAL_SECONDS=5,TEMPORARY_REVEAL_RADIUS=3,OBJECT_REVEAL_RADIUS=4.25,SHROUD_TYPE_BITS=3,SHROUD_TYPE_MASK=(1<<SHROUD_TYPE_BITS)-1;!function(e){e[e.Unexplored=0]="Unexplored",e[e.TemporaryReveal=1]="TemporaryReveal",e[e.Explored=2]="Explored"}(ShroudType=ShroudType||{}),function(e){e[e.Darken=8]="Darken"}(ShroudFlag=ShroudFlag||{});class MapShroud{constructor(){this.invalidations=new Map,this.temporaryReveals=new Map,this.fullInvalidation=!1,this._onChange=new EventDispatcher}get onChange(){return this._onChange.asEvent()}fromTiles(e){var t,i=e.getMapSize(),r=e.getMaxTileHeight(),r=this.padding=(r+r%2)/2;this.size={width:i.width+r,height:i.height+r},this.tiles=new Uint8Array(this.size.width*this.size.height),this.tiles.fill(ShroudType.Unexplored),this.tileElevation=new Uint8Array(this.size.width*this.size.height);for(t of e.getAll()){var s=this.getTileIndex(t);this.tileElevation[s]=Math.max(this.tileElevation[s],t.terrainType===TerrainType.Cliff&&0<t.z?t.z-1:t.z)}return this}getSize(){return this.size}getTileIndex(e){var{sx:t,sy:e}=this.rxyzToSxy(e.rx,e.ry,e.z);return t+e*this.size.width}rxyzToSxy(e,t,i){i=(i|=0)+i%2;return{sx:e-i/2+this.padding,sy:t-i/2+this.padding}}sxyzToRxy(e,t,i){return{rx:e+Math.ceil(i/2)-this.padding,ry:t+Math.ceil(i/2)-this.padding}}shroudCoordsToWorld({sx:e,sy:t}){return this.sxyzToRxy(e,t,0)}findTilesAtShroudCoords({sx:t,sy:i},r){var e=r.getMaxTileHeight(),s=e+e%2;let a=[];for(let e=0;e<=s;e+=2){var n=e+e%2,{rx:o,ry:n}=this.sxyzToRxy(t,i,n),n=r.getByMapCoords(o,n);n?.z===e&&a.push(n)}return a}clone(){let e=new MapShroud;return e.tiles=this.tiles.slice(),e.size=this.size,e.padding=this.padding,e.tileElevation=this.tileElevation,e}copy(e){this.tiles=e.tiles.slice(),this.size=e.size,this.padding=e.padding,this.tileElevation=e.tileElevation}merge(e){if(this.size.width!==e.size.width||this.size.height!==e.size.height)throw new Error("Size mismatch");var i=e.tiles;for(let e=0,t=this.tiles.length;e<t;e++)this.tiles[e]=Math.max(i[e]&SHROUD_TYPE_MASK,this.tiles[e]&SHROUD_TYPE_MASK)|(i[e]|this.tiles[e])>>SHROUD_TYPE_BITS<<SHROUD_TYPE_BITS}isShrouded(e,t=0){t=this.rxyzToSxy(e.rx,e.ry,e.z+t);return this.getShroudTypeByShroudCoords(t)===ShroudType.Unexplored}getShroudType(e){return this.tiles[this.getTileIndex(e)]&SHROUD_TYPE_MASK}isFlagged(e,t){return 0!=(this.tiles[this.getTileIndex(e)]&t)}getShroudTypeByTileCoords(e,t,i){return this.getShroudTypeByShroudCoords(this.rxyzToSxy(e,t,i))}getShroudTypeByShroudCoords({sx:e,sy:t}){return e<0||t<0||e>=this.size.width||t>=this.size.height?ShroudType.Unexplored:this.tiles[e+t*this.size.width]&SHROUD_TYPE_MASK}invalidateFull(){this.fullInvalidation=!0}invalidate(e,t,i){var r=e.sx+e.sy*this.size.width;let s=this.invalidations.get(r);s||(s={center:e,elevation:0,radius:0},this.invalidations.set(r,s)),s.elevation=Math.max(s.elevation,t),s.radius=Math.max(s.radius,i)}revealFrom(e){var t,i;e.isBuilding()&&e.wallTrait||(t=e.sight)&&(i=e.tile.z+e.tileElevation,e=this.rxyzToSxy(e.tile.rx,e.tile.ry,i),this.invalidate(e,i,t))}revealAround(e,t){e=this.rxyzToSxy(e.rx,e.ry,e.z);this.invalidate(e,Number.POSITIVE_INFINITY,t)}unrevealAround(e,t){var i=[],e=this.rxyzToSxy(e.rx,e.ry,e.z);this.setValueAround(e,t,Number.POSITIVE_INFINITY,i,ShroudType.Unexplored,ShroudType.Explored),this._onChange.dispatch(this,{type:"incremental",coords:i})}revealTemporarily(e){e=this.rxyzToSxy(e.tile.rx,e.tile.ry,e.tile.z+e.tileElevation);this.temporaryReveals.set(e,TEMPORARY_REVEAL_SECONDS*GameSpeed.BASE_TICKS_PER_SECOND)}revealObject(e){e=this.rxyzToSxy(e.tile.rx,e.tile.ry,e.tile.z+e.tileElevation);this.invalidate(e,Number.POSITIVE_INFINITY,OBJECT_REVEAL_RADIUS)}toggleFlagsAround(e,t,i,r){var s=[],e=this.rxyzToSxy(e.rx,e.ry,e.z);this.setValueAround(e,t,Number.POSITIVE_INFINITY,s,void 0,void 0,r?{setFlags:i}:{clearFlags:i}),this._onChange.dispatch(this,{type:"incremental",coords:s})}update(){let i=[];if(this.invalidations.size){for(var e of this.invalidations.values())this.setValueAround(e.center,e.radius,e.elevation,i,ShroudType.Explored,[ShroudType.Unexplored,ShroudType.TemporaryReveal]);this.invalidations.clear()}this.temporaryReveals.size&&this.temporaryReveals.forEach((e,t)=>{e<=0?(this.setValueAround(t,TEMPORARY_REVEAL_RADIUS,Number.POSITIVE_INFINITY,i,ShroudType.Unexplored,ShroudType.TemporaryReveal),this.temporaryReveals.delete(t)):(e===TEMPORARY_REVEAL_SECONDS*GameSpeed.BASE_TICKS_PER_SECOND&&this.setValueAround(t,TEMPORARY_REVEAL_RADIUS,Number.POSITIVE_INFINITY,i,ShroudType.TemporaryReveal,ShroudType.Unexplored),this.temporaryReveals.set(t,e-1))}),this.fullInvalidation?(this.fullInvalidation=!1,this._onChange.dispatch(this,{type:"full"})):i.length&&this._onChange.dispatch(this,{type:"incremental",coords:i})}setValueAround(r,s,a,n,o,l=void 0,{setFlags:h,clearFlags:c}={}){var e=Math.ceil(s),t=clamp(r.sx-e,0,this.size.width-1),u=clamp(r.sx+e,0,this.size.width-1),d=clamp(r.sy-e,0,this.size.height-1),p=clamp(r.sy+e,0,this.size.height-1),g=this.size.width;for(let i=t;i<=u;i++)for(let t=d;t<=p;t++){var m=i+t*g,y=this.tiles[m]&SHROUD_TYPE_MASK,T=this.tiles[m]>>SHROUD_TYPE_BITS<<SHROUD_TYPE_BITS;let e=T;void 0!==h&&(e|=h),void 0!==c&&(e&=~c),void 0!==l&&("number"!=typeof l?!l.includes(y):l!==y)||((i-r.sx)*(i-r.sx)+(t-r.sy)*(t-r.sy)>s*s+1||this.tileElevation[m]>=a+4||(this.tiles[m]=(o??y)|e,y===o&&T===e||n.push({sx:i,sy:t})))}}revealAll(){this.tiles.fill(ShroudType.Explored),this._onChange.dispatch(this,{type:"clear"})}reset(){this.tiles.fill(ShroudType.Unexplored),this._onChange.dispatch(this,{type:"cover"})}}const GAP_REFRESH_SECONDS=5;class GapGeneratorTrait{constructor(e){this.radiusTiles=e,this.refreshTicks=0}[NotifyTick_NotifyTick.onTick](e,t){0<this.refreshTicks&&this.refreshTicks--,this.refreshTicks<=0&&this.update(e,t)}[NotifySpawn.onSpawn](e,t){this.markGapTilesForFriendlies(e,e.owner,t,!0)}[NotifyUnspawn.onUnspawn](e,t){this.markGapTilesForFriendlies(e,e.owner,t,!1),this.update(e,t)}[NotifyOwnerChange.onChange](e,t,i){this.markGapTilesForFriendlies(e,t,i,!1),this.markGapTilesForFriendlies(e,e.owner,i,!0),this.update(e,i)}[NotifyWarpChange_NotifyWarpChange.onChange](e,t,i){this.markGapTilesForFriendlies(e,e.owner,t,!i),i&&this.update(e,t)}markGapTilesForFriendlies(i,e,r,t){let s=[e,...r.alliances.getAllies(e)],a;for(var n of s){let e=r.mapShroudTrait.getPlayerShroud(n);if(e&&(e.toggleFlagsAround(i.tile,this.radiusTiles,ShroudFlag.Darken,t),!t)){if(!a){let t=new RangeHelper(r.map.tileOccupation);a=s.map(e=>[...e.buildings]).flat().filter(e=>e.gapGeneratorTrait&&e!==i&&t.tileDistance(e,i)<=e.gapGeneratorTrait.radiusTiles+this.radiusTiles)}for(var o of a)e.toggleFlagsAround(o.tile,o.gapGeneratorTrait.radiusTiles,ShroudFlag.Darken,!0)}}}update(t,i){this.refreshTicks=GAP_REFRESH_SECONDS*GameSpeed.BASE_TICKS_PER_SECOND;let r;var s,a,n,o,l=t.owner.buildings.has(t)&&t.poweredTrait?.isPoweredOn();for(s of i.getCombatants())if(s!==t.owner&&!i.alliances.areAllied(t.owner,s)){let e=i.mapShroudTrait.getPlayerShroud(s);if(e)if(l){e.unrevealAround(t.tile,this.radiusTiles),r||(n=this.radiusTiles+TechnoRules.MAX_SIGHT,a=new Vector2(t.tile.rx,t.tile.ry).addScalar(-n),n=new Vector2(t.tile.rx,t.tile.ry).addScalar(n),r=i.map.technosByTile.queryRange(new Box2(a,n)));for(o of r)o.owner===s||i.alliances.areAllied(o.owner,s)?e.revealFrom(o):o.rules.revealToAll&&e.revealObject(o)}else[...s.buildings].some(e=>e.rules.spySat)&&e.revealAround(t.tile,this.radiusTiles)}}}const SCAN_FRAMES=GameSpeed.BASE_TICKS_PER_SECOND;class PsychicDetectorTrait{constructor(e){this.radiusTiles=e,this.detectionLines=[],this.nextScan=SCAN_FRAMES}[NotifyTick_NotifyTick.onTick](e,t){e.owner.powerTrait?.isLowPower()?this.disable():(0<this.nextScan&&this.nextScan--,this.nextScan<=0&&(this.nextScan=SCAN_FRAMES,this.detectionLines=this.scan(e,t)))}[NotifyWarpChange_NotifyWarpChange.onChange](e,t,i){i&&this.disable()}disable(){this.detectionLines.length&&(this.detectionLines=[],this.nextScan=0)}scan(t,i){var e=i.getCombatants().filter(e=>e!==t.owner&&!i.alliances.areAllied(e,t.owner));let r=[],s=new RangeHelper(i.map.tileOccupation);var a,n,o,l=e=>s.distance2(e,t)/Coords.LEPTONS_PER_TILE<=this.radiusTiles;for(a of e)for(var h of a.getOwnedObjects())h.attackTrait?.currentTarget?l((n=h.attackTrait.currentTarget).obj??n.tile)&&r.push({source:h,target:n}):h.isUnit()&&h.unitOrderTrait.targetLinesConfig&&((o=h.unitOrderTrait.targetLinesConfig).target?l(o.target)&&(n=i.createTarget(o.target,o.target.tile),r.push({source:h,target:n})):(o=o.pathNodes[0])&&l(o.tile)&&(o=i.createTarget(o.onBridge,o.tile),r.push({source:h,target:o})));return r}}const HEALING_SECONDS=5;class HospitalTrait{constructor(){this.healQueue=[]}addToHealQueue(e){return this.healQueue.push(e),this.healQueue.length-1}unitIsFirstInHealQueue(e){return this.healQueue[0]===e}removeFromHealQueue(e){e=this.healQueue.indexOf(e);-1!==e&&this.healQueue.splice(e,1)}startHealing(e){if(this.unit)throw new Error(`Already busy healing unit ${ObjectType[this.unit.type]}#${this.unit.id}}`);this.unit=e,this.healTicks=HEALING_SECONDS*GameSpeed.BASE_TICKS_PER_SECOND}[NotifyTick_NotifyTick.onTick](e,t){var i;this.healQueue=this.healQueue.filter(e=>!e.isDestroyed&&!e.isCrashing),this.unit&&void 0!==this.healTicks&&(0<this.healTicks&&this.healTicks--,this.healTicks<=0&&(this.healTicks=void 0,this.removeFromHealQueue(this.unit),this.unit.healthTrait.healToFull(e,t),e.ammoTrait&&e.ammoTrait.ammo--,this.evacuate(this.unit,e,t),i=this.unit,this.unit=void 0,t.events.dispatch(new UnitRepairFinishEvent(i,e))))}[NotifyDestroy.onDestroy](e,t,i){this.unit&&(this.unit.deathType=e.deathType,t.destroyObject(this.unit,i,!0),this.unit=void 0)}evacuate(t,i,r){let e;var s={x:i.tile.rx,y:i.tile.ry+i.art.foundation.height},s=r.map.tiles.getByMapCoords(s.x,s.y);s&&r.map.isWithinBounds(s)&&this.canEvacuateTo(s,t,i,r)&&(e=s),e=e||new RadialTileFinder(r.map.tiles,r.map.mapBounds,i.tile,i.art.foundation,1,1,e=>this.canEvacuateTo(e,t,i,r)).getNextTile(),e?(r.unlimboObject(t,e),t.unitOrderTrait.addTask(new ScatterTask(r))):r.destroyObject(t,{player:t.owner})}canEvacuateTo(e,t,i,r){return 0<r.map.terrain.getPassableSpeed(e,t.rules.speedType,t.isInfantry(),!1)&&Math.abs(e.z-i.tile.z)<2&&!r.map.terrain.findObstacles({tile:e,onBridge:void 0},t).length}}class DelayedKillTrait{constructor(){this.timer=new Timer}isActive(){return this.timer.isActive()}activate(e,t){this.isActive()||(this.timer.setActiveFor(e),this.attackerInfo=t)}[NotifyTick_NotifyTick.onTick](e,t){this.timer.isActive()&&!0===this.timer.tick(t.currentTick)&&(e.invulnerableTrait.isActive()||e.isBuilding()&&e.cabHutTrait||t.destroyObject(e,this.attackerInfo,!0,!0))}}!function(e){e[e.BuildUp=0]="BuildUp",e[e.Ready=1]="Ready",e[e.BuildDown=2]="BuildDown"}(BuildStatus=BuildStatus||{});class Building extends Techno_Techno{get buildStatus(){return this._buildStatus}static factory(e,t,i,r,s,a){let n=new this(e,t,r);return t.canBeOccupied&&(n.garrisonTrait=new GarrisonTrait(n,i.audioVisual.conditionRed,t.maxNumberOccupants),n.traits.add(n.garrisonTrait)),t.canC4&&!t.wall&&(n.c4ChargeTrait=new C4ChargeTrait,n.traits.add(n.c4ChargeTrait)),t.eligibleForDelayKill&&(n.delayedKillTrait=new DelayedKillTrait,n.traits.add(n.delayedKillTrait)),t.bridgeRepairHut&&(n.cabHutTrait=new CabHutTrait(n,a),n.traits.add(n.cabHutTrait)),t.crewed&&(n.crewedTrait=new CrewedTrait,n.traits.add(n.crewedTrait)),t.turret&&(n.turretTrait=new TurretTrait,n.traits.add(n.turretTrait)),t.overpowerable&&(n.overpoweredTrait=new OverpoweredTrait(n),n.traits.add(n.overpoweredTrait)),(t.powered&&0!==t.power||t.needsEngineer)&&(n.poweredTrait=new PoweredTrait(n),n.traits.add(n.poweredTrait)),(t.factory||t.cloning)&&(n.factoryTrait=new FactoryTrait(t.cloning?FactoryType.InfantryType:t.factory,t.cloning),n.traits.add(n.factoryTrait)),t.superWeapon&&(n.superWeaponTrait=new SuperWeaponTrait(t.superWeapon),n.traits.add(n.superWeaponTrait)),t.numberOfDocks&&(n.dockTrait=new DockTrait(n,s,t.numberOfDocks,r.dockingOffsets),n.traits.add(n.dockTrait),t.helipad&&(n.helipadTrait=new HelipadTrait,n.traits.add(n.helipadTrait)),(t.unitRepair||t.unitReload)&&(n.unitRepairTrait=new UnitRepairTrait,n.traits.add(n.unitRepairTrait)),t.unitReload&&(n.unitReloadTrait=new UnitReloadTrait,n.traits.add(n.unitReloadTrait))),t.hospital&&(n.hospitalTrait=new HospitalTrait,n.traits.add(n.hospitalTrait)),(t.factory||t.cloning||t.numberOfDocks)&&(n.rallyTrait=new RallyTrait,n.traits.add(n.rallyTrait)),t.freeUnit&&n.traits.add(new FreeUnitTrait),t.produceCashStartup&&n.traits.add(new OilDerrickTrait),t.wall&&(n.wallTrait=new WallTrait,n.traits.add(n.wallTrait)),t.gapGenerator&&(n.gapGeneratorTrait=new GapGeneratorTrait(t.gapRadiusInCells),n.traits.add(n.gapGeneratorTrait)),t.psychicDetectionRadius&&(n.psychicDetectorTrait=new PsychicDetectorTrait(t.psychicDetectionRadius),n.traits.add(n.psychicDetectorTrait)),n}constructor(e,t,i){super(ObjectType.Building,e,t,i),this.showWeaponRange=!1,this.direction=0,this._buildStatus=BuildStatus.BuildUp,this.lastBuildStatus=this.buildStatus}isBuilding(){return!0}getFoundation(){return this.art.foundation}getFoundationCenterOffset(){var e=this.getFoundation();return new Vector2(e.width/2*Coords.LEPTONS_PER_TILE,e.height/2*Coords.LEPTONS_PER_TILE)}update(e){this.buildStatus!==BuildStatus.BuildUp||this.unitOrderTrait.hasTasks()||this.unitOrderTrait.addTask(new WaitForBuildUpTask(e.rules.general.buildupTime,e)),this.attackTrait?.setDisabled(this.buildStatus!==BuildStatus.Ready||!!this.poweredTrait&&!this.poweredTrait.isPoweredOn()),super.update(e)}setBuildStatus(e,t){this._buildStatus=e;let i=this.lastBuildStatus;this.buildStatus!==i&&(this.lastBuildStatus=this.buildStatus,this.traits.filter(NotifyBuildStatus).forEach(e=>{e[NotifyBuildStatus.onStatusChange](i,this,t)}),t.events.dispatch(new BuildStatusChangeEvent(this,this.buildStatus)))}}class Terrain_Terrain extends GameObject{static factory(e,t,i){return new this(e,t,i)}constructor(e,t,i){super(ObjectType.Terrain,e,t,i),this.radarInvisible=this.rules.radarInvisible}}class Overlay_Overlay extends GameObject{static factory(e,t,i){let r=new this(e,t,i);return t.wall&&(r.wallTrait=new WallTrait,r.traits.add(r.wallTrait)),r}constructor(e,t,i){super(ObjectType.Overlay,e,t,i),this.radarInvisible=this.rules.radarInvisible}isTiberium(){return void 0!==OreOverlayTypes.getOverlayTibType(this.overlayId)}isBridge(){return BridgeOverlayTypes.isBridge(this.overlayId)}isXBridge(){return BridgeOverlayTypes.isXBridge(this.overlayId)}isHighBridge(){return BridgeOverlayTypes.isHighBridge(this.overlayId)}isLowBridge(){return BridgeOverlayTypes.isLowBridge(this.overlayId)}isBridgePlaceholder(){return BridgeOverlayTypes.isBridgePlaceholder(this.overlayId)}getFoundation(){let e={width:1,height:1};return this.isBridge()&&(this.isXBridge()?e.height+=2:e.width+=2),e}getLandType(){return this.rules.wall?LandType.Wall:this.isTiberium()?LandType.Tiberium:this.isBridge()&&this.isHighBridge()?LandType.Road:this.rules.land}}class Smudge_Smudge extends GameObject{static factory(e,t,i){return new this(e,t,i)}constructor(e,t,i){super(ObjectType.Smudge,e,t,i)}getFoundation(){return{width:this.rules.width,height:this.rules.height}}}class TeleportMoveToRefineryTask extends MoveTask{constructor(e,t,i,r){super(e,i??t,!1,{closeEnoughTiles:i?void 0:0,strictCloseEnough:!i}),this.teleportTile=t,this.teleportCondition=r}onStart(e){if(super.onStart(e),!e.harvesterTrait||e.rules.locomotor!==LocomotorType.Chrono)throw new Error(`Vehicle ${e.name} is not a chrono miner`)}onTick(e){return!e.moveTrait.isDisabled()&&(!(this.isCancelling()||e.moveTrait.moveState!==MoveState.ReachedNextWaypoint||e.tile===this.teleportTile||!this.tryTeleportToRefinery(e))||!0===super.onTick(e)&&(this.isCancelling()||e.tile===this.teleportTile||this.tryTeleportToRefinery(e),!0))}tryTeleportToRefinery(e){return(!this.teleportCondition||!1!==this.teleportCondition(e,this.teleportTile))&&(!this.game.map.terrain.findObstacles({tile:this.teleportTile,onBridge:void 0},e).length&&(e.moveTrait.teleportUnitToTile(this.teleportTile,void 0,!0,!0,this.game),e.zone===ZoneType.Air&&(e.zone=ZoneType.Ground,e.position.tileElevation=0),!0))}}const RETRY_MOVE_SECONDS=5,LOAD_RATE_SECONDS=1,ADJACENT_SCAN_PRIORITIES=[[8,5,6],[3,0,2],[7,4,1]];class GatherOreTask extends Task{constructor(e,t,i=!1){super(),this.game=e,this.initialTarget=t,this.explicitOrder=i,this.forceMoveTried=!1,this.useChildTargetLines=!0,this.preventOpportunityFire=!1,this.rangeHelper=new RangeHelper(e.map.tileOccupation),this.scanNearRadius=e.rules.ai.tiberiumNearScan,this.scanFarRadius=e.rules.ai.tiberiumFarScan}onStart(e){if(!e.isVehicle()||!e.harvesterTrait)throw new Error(`Unit ${e.name} is not a harvester.`);e.harvesterTrait.status=HarvesterStatus.MovingToOreSite,e.harvesterTrait.lastGatherExplicit=this.explicitOrder}onEnd(e){e.harvesterTrait.status!==HarvesterStatus.LookingForOreSite&&(e.harvesterTrait.status=HarvesterStatus.Idle)}onTick(i){if(this.isCancelling())return!0;let r=i.harvesterTrait;if(r.status===HarvesterStatus.MovingToOreSite){var e=this.target;if(this.target=this.findClosestReachableOreSite(i,this.target||this.initialTarget?.landType!==LandType.Tiberium?r.lastOreSite??i.tile:this.initialTarget,!0),r.lastOreSite=this.target,!this.target){r.status=HarvesterStatus.LookingForOreSite;let e=this.getRefineryOnTile(i.tile);if(e&&1===i.unitOrderTrait.getTasks().length){let t=i.rules.movementZone===MovementZone.Fly;var s=new RadialTileFinder(this.game.map.tiles,this.game.map.mapBounds,e.tile,e.getFoundation(),1,5,e=>t||0<this.game.map.terrain.getPassableSpeed(e,i.rules.speedType,i.isInfantry(),!1)&&Math.abs(e.z-i.tile.z)<2&&!this.game.map.terrain.findObstacles({tile:e,onBridge:void 0},i).length).getNextTile();s&&i.unitOrderTrait.addTasks(new MoveTask(this.game,s,!1),new CallbackTask(()=>{[MoveResult.Success,MoveResult.CloseEnough,MoveResult.Cancel].includes(i.moveTrait.lastMoveResult)||this.children.push(new WaitMinutesTask(1/60))}))}return!0}s=this.game.rules.general.closeEnough,e=e&&this.rangeHelper.tileDistance(i.tile,this.target)<=s;if(!(i.tile===this.target||i.tile.landType===LandType.Tiberium&&e)){if(i.tile!==this.target&&e&&i.tile.landType!==LandType.Tiberium){e=this.findClosestReachableOreSite(i,i.tile,!1,!0);if(e)this.target=e,r.lastOreSite=this.target;else{if(!this.forceMoveTried)return this.forceMoveTried=!0,this.children.push(new MoveTask(this.game,this.target,!1,{closeEnoughTiles:0,strictCloseEnough:!0})),!1;if(this.forceMoveTried=!1,!r.isEmpty())return this.returnOreIfPossible(i),!0;e=this.findClosestReachableOreSite(i,i.tile,!0,!0);if(!e)return r.status=HarvesterStatus.LookingForOreSite,!0;this.target=e,r.lastOreSite=this.target}}return this.children.push(new MoveTask(this.game,this.target,!1,{closeEnoughTiles:s}),new CallbackTask(()=>{[MoveResult.Success,MoveResult.CloseEnough,MoveResult.Cancel].includes(i.moveTrait.lastMoveResult)||this.children.push(new WaitMinutesTask(RETRY_MOVE_SECONDS/60))})),!1}this.target=i.tile,r.lastOreSite=this.target,r.status=HarvesterStatus.Harvesting,this.forceMoveTried=!1}if(r.status!==HarvesterStatus.Harvesting)return!1;{if(r.isFull())return this.returnOreIfPossible(i),!0;let e=this.game.map.getObjectsOnTile(i.tile).find(e=>e.isOverlay()&&e.isTiberium());if(!e)return this.findClosestReachableOreSite(i,i.tile,!1)||r.isEmpty()?(r.status=HarvesterStatus.MovingToOreSite,this.onTick(i)):(this.returnOreIfPossible(i),!0);let t=e.traits.get(TiberiumTrait);s=t.collectBail();return(t.getBailCount()||this.game.unspawnObject(e),void 0===s||r.addBails(s,1),[...i.owner.buildings].some(e=>e.rules.refinery)||this.explicitOrder)?(this.children.push(new WaitMinutesTask(LOAD_RATE_SECONDS/60)),!1):!0}}findClosestReachableOreSite(t,i,e,r=!1){let s=t.rules.movementZone===MovementZone.Fly;var a=t.rules.speedType,n=t.isInfantry();let o=!s&&this.game.map.terrain.getPassableSpeed(t.tile,a,n,t.onBridge)?this.game.map.terrain.getIslandIdMap(a,n):void 0,l=o?.get(t.tile,t.onBridge);var h,n=e=>e.landType===LandType.Tiberium&&o?.get(e,!1)===l&&(!r||(s||!this.game.map.terrain.findObstacles({tile:e,onBridge:void 0},t).length));if(n(i))return i;let c=1;if(!e){let e=new RadialTileFinder(this.game.map.tiles,this.game.map.mapBounds,i,{width:1,height:1},c,c,n),t=[];for(;h=e.getNextTile();)t.push(h);if(t.length){let e=t.map(e=>{let t=this.game.map.getObjectsOnTile(e).find(e=>e.isOverlay()&&e.isTiberium());if(!t)throw new Error(`Ore should exist on tile ${e.rx},${e.ry} b/c of landType`);var i=t.traits.get(TiberiumTrait);return{tile:e,ore:t,tibTrait:i}});return e.sort((e,t)=>1e5*(t.tibTrait.rules.value-e.tibTrait.rules.value)+1e3*(t.ore.value-e.ore.value)+(ADJACENT_SCAN_PRIORITIES[1+t.tile.ry-i.ry][1+t.tile.rx-i.rx]-ADJACENT_SCAN_PRIORITIES[1+e.tile.ry-i.ry][1+e.tile.rx-i.rx])),e[0].tile}c=2}e=e?this.scanFarRadius:this.scanNearRadius;let u=new RadialTileFinder(this.game.map.tiles,this.game.map.mapBounds,i,{width:1,height:1},c,e,n);return u.getNextTile()}getRefineryOnTile(e){return this.game.map.getObjectsOnTile(e).find(e=>e.isBuilding()&&e.rules.refinery)}returnOreIfPossible(e){1===e.unitOrderTrait.getTasks().length&&e.unitOrderTrait.addTask(new ReturnOreTask(this.game))}getTargetLinesConfig(e){return{pathNodes:this.initialTarget?[{tile:this.initialTarget,onBridge:void 0}]:[]}}}class ReturnOreTask extends Task{constructor(e,t,i=!1,r=!1){super(),this.game=e,this.forceTarget=t,this.resetLastOreSite=i,this.explicitOrder=r,this.useChildTargetLines=!0,this.preventOpportunityFire=!1,this.rangeHelper=new RangeHelper(e.map.tileOccupation)}onStart(e){if(!e.isVehicle()||!e.harvesterTrait)throw new Error(`Unit ${e.name} is not a harvester.`);e.harvesterTrait.status=HarvesterStatus.MovingToRefinery,this.resetLastOreSite&&(e.harvesterTrait.lastOreSite=void 0)}onEnd(e){this.target?.isSpawned&&(this.target.dockTrait.undockUnit(e),this.target.dockTrait.unreserveDockForUnit(e)),e.harvesterTrait.status!==HarvesterStatus.LookingForRefinery&&(e.harvesterTrait.status=HarvesterStatus.Idle)}onTick(r){if(this.isCancelling())return!0;let s=r.harvesterTrait;if(s.status===HarvesterStatus.LookingForRefinery)return!0;if(s.status===HarvesterStatus.MovingToRefinery){if(!this.target||!this.isValidTargetRefinery(this.target,r)||r.tile!==this.findRefineryDockingTile(this.target)){var a=this.forceTarget??this.findClosestReachableRefinery(r);if(!a)return s.status=HarvesterStatus.LookingForRefinery,!0;this.target&&this.target!==a&&this.target.dockTrait.hasReservedDockForUnit(r)&&this.target.dockTrait.unreserveDockForUnit(r),this.target=a}let e=this.target.dockTrait.getFirstAvailableDockNumber(),t=!1;void 0===e&&(e=this.target.dockTrait.getFirstEmptyDockNumber(),void 0!==e&&(t=!this.target.dockTrait.hasReservedDockForUnit(r)));let i=this.findRefineryDockingTile(this.target);var n=this.rangeHelper.tileDistance(r,i);if(void 0===e||t||n>this.game.rules.general.harvesterTooFarDistance&&!this.explicitOrder){var o=this.findReachableQueueingTile(r);return o?(r.tile!==o&&this.children.push(r.rules.teleporter?new TeleportMoveToRefineryTask(this.game,i,o,()=>this.chronoMinerCanTeleport(r,i,this.target)):new MoveTask(this.game,o,!1),new CallbackTask(()=>{r.moveTrait.lastMoveResult===MoveResult.Fail?s.status=HarvesterStatus.LookingForRefinery:r.moveTrait.lastMoveResult===MoveResult.CloseEnough?this.children.push(new WaitMinutesTask(5/60)):r.moveTrait.lastMoveResult===MoveResult.Success&&this.children.push(new WaitMinutesTask(2/60))})),!1):!0}if(this.target.dockTrait.hasReservedDockForUnit(r)||this.target.dockTrait.reserveDockAt(r,e),void 0===this.reservedDockNumber&&(this.reservedDockNumber=this.target.dockTrait.getReservedDockForUnit(r)),r.tile!==i)return this.children.push(r.rules.teleporter?new TeleportMoveToRefineryTask(this.game,i,void 0,()=>this.chronoMinerCanTeleport(r,i,this.target)):new MoveTask(this.game,i,!1,{closeEnoughTiles:0,strictCloseEnough:!0}),new CallbackTask(()=>{r.moveTrait.lastMoveResult===MoveResult.Fail&&(s.status=HarvesterStatus.LookingForRefinery)})),!1;s.status=HarvesterStatus.Docking}if(!this.isValidTargetRefinery(this.target,r))return s.status=HarvesterStatus.MovingToRefinery,this.forceTarget=void 0,this.onTick(r);if(s.status===HarvesterStatus.Docking){if(270!==r.direction)return this.children.push(new TurnTask(270)),!1;this.target.dockTrait.dockUnitAt(r,this.reservedDockNumber),this.reservedDockNumber=void 0,s.status=HarvesterStatus.PreparingToUnload}if(s.status===HarvesterStatus.PreparingToUnload)return this.preventOpportunityFire=!0,this.children.push(new WaitMinutesTask(2/60)),s.status=HarvesterStatus.Unloading,!1;if(s.status!==HarvesterStatus.Unloading)return!1;var e=s.getBails().reduce((e,[t,i])=>e+i*this.game.rules.getTiberium(t).value,0),a=e,n=[...this.target.owner.buildings].filter(e=>e.rules.orePurifier&&(!e.poweredTrait||!this.target.owner.powerTrait?.isLowPower())).length,o=this.game.rules.general.purifierBonus;return a+=n*Math.floor(e*o),this.target.owner.credits+=a,this.target.owner.creditsGained+=a,s.empty(),1===r.unitOrderTrait.getTasks().length&&r.unitOrderTrait.addTask(new GatherOreTask(this.game)),!0}isValidTargetRefinery(e,t){return e.isSpawned&&this.game.areFriendly(e,t)&&!e.warpedOutTrait.isActive()}findClosestReachableRefinery(i){let r=this.rangeHelper;var e=i.zone===ZoneType.Air,t=i.rules.speedType,s=i.isInfantry();let a=!e&&this.game.map.terrain.getPassableSpeed(i.tile,t,s,i.onBridge)?this.game.map.terrain.getIslandIdMap(t,s):void 0,n=[...i.owner.buildings].filter(e=>e.rules.refinery&&e.dockTrait&&!e.warpedOutTrait.isActive()&&(e=>i.rules.teleporter||a?.get(e,!1)===a?.get(i.tile,i.onBridge))(this.findRefineryDockingTile(e))).sort((e,t)=>r.distance2(i,e)-r.distance2(i,t));t=n[0],s=n.find(e=>0<e.dockTrait.getAvailableDockCount());return!s||t&&r.tileDistance(i,s.centerTile)-r.tileDistance(i,t.centerTile)>this.game.rules.general.harvesterTooFarDistance?t:s}findReachableQueueingTile(t){if(this.target.art.queueingCell){var e=new Vector2(this.target.tile.rx,this.target.tile.ry).add(this.target.art.queueingCell),e=this.game.map.tiles.getByMapCoords(e.x,e.y);if(e&&this.isValidQueueingTile(e,t))return e}return new RadialTileFinder(this.game.map.tiles,this.game.map.mapBounds,this.target.tile,this.target.getFoundation(),1,1,e=>this.isValidQueueingTile(e,t)).getNextTile()}isValidQueueingTile(e,t){var i=t.zone===ZoneType.Air,r=t.rules.speedType,s=t.isInfantry();let a=!i&&this.game.map.terrain.getPassableSpeed(t.tile,r,s,t.onBridge)?this.game.map.terrain.getIslandIdMap(r,s):void 0;return i||a?.get(e,!1)===a?.get(t.tile,t.onBridge)&&Math.abs(e.z-this.target.tile.z)<2&&!e.onBridgeLandType}findRefineryDockingTile(e){e={x:e.tile.rx+e.getFoundation().width-1,y:e.tile.ry+Math.floor(e.getFoundation().height/2)};return this.game.map.tiles.getByMapCoords(e.x,e.y)}chronoMinerCanTeleport(e,t,i){let r=this.rangeHelper;t=r.tileDistance(e,t);return!(!this.forceTarget&&t>this.game.rules.general.chronoHarvTooFarDistance)&&(!(t<=1)&&(!!this.isValidTargetRefinery(i,e)&&!(0===i.dockTrait.getAvailableDockCount()&&!i.dockTrait.hasReservedDockForUnit(e))))}}(NotifyOrder=NotifyOrder||{}).onPush=Symbol(),function(e){e[e.Move=0]="Move",e[e.ForceMove=1]="ForceMove",e[e.Attack=2]="Attack",e[e.ForceAttack=3]="ForceAttack",e[e.AttackMove=4]="AttackMove",e[e.Guard=5]="Guard",e[e.GuardArea=6]="GuardArea",e[e.Capture=7]="Capture",e[e.Occupy=8]="Occupy",e[e.Deploy=9]="Deploy",e[e.DeploySelected=10]="DeploySelected",e[e.Stop=11]="Stop",e[e.Cheer=12]="Cheer",e[e.Dock=13]="Dock",e[e.Gather=14]="Gather",e[e.Repair=15]="Repair",e[e.Scatter=16]="Scatter",e[e.EnterTransport=17]="EnterTransport",e[e.PlaceBomb=18]="PlaceBomb"}(OrderType=OrderType||{}),function(e){e[e.Idle=0]="Idle",e[e.LookingForOreSite=1]="LookingForOreSite",e[e.MovingToOreSite=2]="MovingToOreSite",e[e.Harvesting=3]="Harvesting",e[e.LookingForRefinery=4]="LookingForRefinery",e[e.MovingToRefinery=5]="MovingToRefinery",e[e.Docking=6]="Docking",e[e.PreparingToUnload=7]="PreparingToUnload",e[e.Unloading=8]="Unloading"}(HarvesterStatus=HarvesterStatus||{});const CHECK_REFINERY_SECONDS=5,CHECK_EXTRA_REFINERY_SECONDS=25,CHECK_ORE_SITE_SECONDS=20;class HarvesterTrait{get ore(){return this._ore}get gems(){return this._gems}constructor(e){this.storage=e,this._ore=0,this._gems=0,this.bails=new Map,this.status=HarvesterStatus.Idle,this.lastGatherExplicit=!1,this.autoGatherOnNextIdle=!1,this.ticksSinceLastRefineryCheck=0,this.ticksSinceLastOreCheck=0}addBails(e,t){this.bails.set(e,(this.bails.get(e)??0)+t),e===TiberiumType.Gems?this._gems+=t:this._ore+=t}getBails(){return[...this.bails.entries()]}[NotifySpawn.onSpawn](e,t){e.owner.isCombatant()&&(t.afterTick(()=>{e.unitOrderTrait.addTask(new GatherOreTask(t))}),e.attackTrait?.increasePassiveScanCooldown(1))}[NotifyOwnerChange.onChange](e,t,i){(!t.isCombatant()&&e.owner.isCombatant()||i.alliances.areAllied(e.owner,t))&&i.afterTick(()=>{e.unitOrderTrait.addTask(new GatherOreTask(i))})}[NotifyTick_NotifyTick.onTick](e,t){this.status===HarvesterStatus.LookingForRefinery?this.ticksSinceLastRefineryCheck++>CHECK_REFINERY_SECONDS*GameSpeed.BASE_TICKS_PER_SECOND&&(this.ticksSinceLastRefineryCheck=0,e.unitOrderTrait.hasTasks()?this.ticksSinceLastRefineryCheck=-CHECK_EXTRA_REFINERY_SECONDS*GameSpeed.BASE_TICKS_PER_SECOND:[...e.owner.buildings].some(e=>e.rules.refinery)||this.lastGatherExplicit?e.unitOrderTrait.addTask(new ReturnOreTask(t)):this.status=HarvesterStatus.Idle):this.status===HarvesterStatus.LookingForOreSite?this.ticksSinceLastOreCheck++>CHECK_ORE_SITE_SECONDS*GameSpeed.BASE_TICKS_PER_SECOND&&(this.ticksSinceLastOreCheck=0,e.unitOrderTrait.hasTasks()||e.unitOrderTrait.addTask(new GatherOreTask(t))):this.status===HarvesterStatus.Idle&&this.autoGatherOnNextIdle&&e.unitOrderTrait.isIdle()&&e.tile.landType===LandType.Tiberium&&(this.autoGatherOnNextIdle=!1,e.unitOrderTrait.addTask(new GatherOreTask(t,e.tile,!0)))}[NotifyTeleport.onBeforeTeleport](e,t,i,r){!r&&e.owner.isCombatant()&&(this.status=HarvesterStatus.Idle,this.lastOreSite=void 0,i&&e.rules.teleporter&&t.afterTick(()=>{e.unitOrderTrait.addTask(new(this.isFull()?ReturnOreTask:GatherOreTask)(t))}))}[NotifyOrder.onPush](e,t){this.autoGatherOnNextIdle=[OrderType.AttackMove,OrderType.Move,OrderType.ForceMove,OrderType.Scatter].includes(t),[HarvesterStatus.LookingForRefinery,HarvesterStatus.LookingForOreSite].includes(this.status)&&(this.status=HarvesterStatus.Idle)}isFull(){return this.ore+this.gems>=this.storage}isEmpty(){return!this.ore&&!this.gems}empty(){this.bails.clear(),this._ore=this._gems=0}getHash(){return 100*this.ore+this.gems}debugGetState(){return{ore:this.ore,gems:this.gems}}}class LeaveTransportEvent{constructor(e){this.target=e,this.type=EventType.LeaveTransport}}class TransportTrait{constructor(e){this.obj=e,this.units=[],this.loadQueue=[]}unitFitsInside(e){return e.rules.size<=this.obj.rules.sizeLimit&&e.rules.size<=this.getAvailableCapacity()}getOccupiedCapacity(){return this.units.reduce((e,t)=>e+t.rules.size,0)}getMaxCapacity(){return this.obj.rules.passengers}getAvailableCapacity(){return this.getMaxCapacity()-this.getOccupiedCapacity()}addToLoadQueue(e){return this.loadQueue.push(e),this.loadQueue.length-1}unitIsFirstInLoadQueue(e){return this.loadQueue[0]===e}removeFromLoadQueue(e){e=this.loadQueue.indexOf(e);-1!==e&&this.loadQueue.splice(e,1)}[NotifyTick_NotifyTick.onTick](e,t){this.loadQueue=this.loadQueue.filter(e=>!e.isDestroyed&&!e.isCrashing)}[NotifyDestroy.onDestroy](e,t,i,r){var s=!!e.armedTrait?.deathWeapon,a=i?.weapon?.warhead.rules.parasite;if(r||s||e.zone===ZoneType.Air||a)for(var n of this.units)s&&n.armedTrait&&(n.armedTrait.deathWeapon=void 0),n.position.tileElevation=e.position.tileElevation,n.zone=e.zone,n.onBridge=e.onBridge,n.position.tile=e.tile,n.deathType=e.deathType,t.destroyObject(n,i,!0);else this.spawnSurvivors(t);this.units=[]}spawnSurvivors(e){var t=this.obj;if(this.units.length){for(var i of this.units)if(0<e.map.terrain.getPassableSpeed(t.tile,i.rules.speedType,i.isInfantry(),t.onBridge)){i.owner.addOwnedObject(i),i.position.tileElevation=t.onBridge?e.map.tileOccupation.getBridgeOnTile(t.tile).tileElevation:0,i.onBridge=t.onBridge,i.zone=e.map.getTileZone(t.tile,!t.onBridge),e.unlimboObject(i,t.tile),i.unitOrderTrait.addTask(new ScatterTask(e));const r=e.getUnitSelection();r.isSelected(t)&&r.addToSelection(i)}else i.position.tileElevation=t.position.tileElevation,i.zone=t.zone,i.onBridge=t.onBridge,i.position.tile=t.tile,i.zone===ZoneType.Water&&(i.deathType=DeathType.Sink),i.armedTrait?.deathWeapon&&(i.armedTrait.deathWeapon=void 0),e.destroyObject(i,{player:i.owner});e.events.dispatch(new LeaveTransportEvent(t))}}getHash(){return fnv32a(this.units.map(e=>e.getHash()))}debugGetState(){return this.units.map(e=>e.debugGetState())}dispose(){this.obj=void 0}}class GunnerTrait{[NotifyTick_NotifyTick.onTick](e){var t,i;!!e.transportTrait.units.length!==this.lastHadGunner&&(this.lastHadGunner=!!e.transportTrait.units.length,i=t=e.transportTrait.units[0]?.rules.ifvMode??0,(t=e.rules.turretIndexesByIfvMode.get(t)??0)<e.rules.turretCount&&(e.turretNo=t,e.armedTrait?.selectSpecialWeapon(i,e.veteranLevel===VeteranLevel.Elite)))}getUiNameForIfvMode(e,t){switch(e){case 0:return"tip:rocket";case 1:return"tip:repair";case 2:case 4:case 5:return"tip:machinegun";default:return t?"name:"+t.toLowerCase():void 0}}}(NotifyHeal=NotifyHeal||{}).onHeal=Symbol();const getSquidDamageTicks=()=>ROCKING_TICKS+2;class ParasiteableTrait{constructor(e){this.gameObject=e,this.beingBoarded=!1}infest(e,t){this.beingBoarded=!1,this.parasite=e,this.parasiteWeapon=t,e.rules.organic?this.damageTickCooldown=getSquidDamageTicks():this.damageTickCooldown=0,this.lastAttacker=void 0,this.lastExternalBaseDamage=void 0,this.lastExternalDamageTick=void 0,t.warhead.rules.paralyzes&&this.gameObject.moveTrait.setDisabled(!0)}isInfested(){return!(!this.parasite||this.parasite.isDestroyed)||this.beingBoarded}isParalyzed(){return!!this.parasiteWeapon?.warhead.rules.paralyzes}uninfest(){this.parasite&&(this.parasiteWeapon.warhead.rules.paralyzes&&this.gameObject.moveTrait.setDisabled(!1),this.parasite=void 0,this.parasiteWeapon=void 0)}getParasite(){return this.parasite}[NotifyTick_NotifyTick.onTick](r,s){if(this.parasite)if(this.parasite.isDestroyed)this.uninfest();else if(0<this.damageTickCooldown)this.damageTickCooldown--;else{let e=this.parasiteWeapon;this.damageTickCooldown=this.parasite.rules.organic?getSquidDamageTicks():e.getCooldownTicks();let t=e.rules.damage;this.parasite.veteranTrait&&(t*=this.parasite.veteranTrait.getVeteranDamageMultiplier());let i=e.warhead.computeDamage(t,r,s);this.canBeCulled(r,this.parasite,e,s)&&(i=r.healthTrait.getHitPoints()),e.warhead.inflictDamage(i,r,{player:this.parasite.owner,obj:this.parasite,weapon:e},s),r.isCrashing?(this.parasiteWeapon.expireCooldown(),this.evictOrDestroyParasite(r,s)):!r.isDestroyed&&r.isVehicle()&&r.zone!==ZoneType.Air&&e.warhead.rules.rocker&&r.applyRocking(90*(.5<=s.generateRandom()?1:-1),1)}}canBeCulled(e,t,i,r){if(!i.warhead.rules.culling)return!1;r=r.rules.audioVisual,r=t.veteranTrait?.isElite()?r.conditionYellow:r.conditionRed;return e.healthTrait.health<=100*r}[NotifyHeal.onHeal](e,t,i,r){!this.parasite||this.parasite.isDestroyed||r===e||e.isAircraft()&&r?.rules.unitReload||(!this.parasite.rules.organic||r?.rules.unitRepair?(this.parasite.deathType=DeathType.None,t.destroyObject(this.parasite,r?{player:r.owner,obj:r}:void 0),this.uninfest()):(r=this.parasite,this.evictOrDestroyParasite(e,t),this.stunParasite(r,t)))}[NotifyDamage.onDamage](e,t,i,r){r?.obj!==this.parasite&&(this.lastAttacker=r,this.lastExternalBaseDamage=r?.weapon?.rules.damage??i,this.lastExternalDamageTick=t.currentTick)}[NotifyAttack.onAttack](i,r,s){if(this.parasite&&!this.parasite.isDestroyed&&r?.weapon?.warhead.rules.sonic){var a=this.parasite;this.evictOrDestroyParasite(i,s),this.stunParasite(a,s);let e=r.weapon.warhead;e.canDamage(a,a.tile,a.zone)&&(i=e.computeDamage(r.weapon.rules.damage,a,s),e.inflictDamage(i,a,r,s));let t=r.obj?.unitOrderTrait.getCurrentTask();t instanceof AttackTask&&t.getWeapon().warhead.rules.sonic&&t.cancel()}}[NotifyDestroy.onDestroy](e,t,i,r){this.parasite&&!this.parasite.isDestroyed&&(r||this.shouldSupressParasite(t,this.parasite)?(this.parasite.deathType=DeathType.None,t.destroyObject(this.parasite,i,r),this.uninfest()):(this.parasiteWeapon.expireCooldown(),this.evictOrDestroyParasite(e,t)))}shouldSupressParasite(e,t){return!t.invulnerableTrait.isActive()&&this.lastExternalBaseDamage&&this.lastExternalBaseDamage>t.rules.suppressionThreshold&&e.currentTick-this.lastExternalDamageTick<2*(this.lastExternalBaseDamage-t.rules.suppressionThreshold)}[NotifyTeleport.onBeforeTeleport](e,t,i,r){i&&r&&this.parasite&&!this.parasite.isDestroyed&&(this.shouldSupressParasite(t,this.parasite)?(this.parasite.deathType=DeathType.None,t.destroyObject(this.parasite,this.lastAttacker),this.uninfest()):(this.parasiteWeapon.expireCooldown(),r=this.parasite,this.evictOrDestroyParasite(e,t,!0),r.isDestroyed||this.stunParasite(r,t)))}stunParasite(e,t){e.unitOrderTrait.addTaskToFront(new WaitMinutesTask(10/60).setCancellable(!1)),e.isVehicle()&&e.submergibleTrait&&(e.submergibleTrait.emerge(e,t),e.cloakableTrait?.uncloak(t),e.submergibleTrait.setCooldown(10*GameSpeed.BASE_TICKS_PER_SECOND))}evictOrDestroyParasite(r,s,a=!1){if(this.parasite&&!this.parasite.isDestroyed){if(s.map.terrain.getPassableSpeed(r.tile,this.parasite.rules.speedType,this.parasite.isInfantry(),r.onBridge)||s.map.getObjectsOnTile(r.tile).find(e=>e.isBuilding())){let t=r.tile,i=r.onBridge;if(!a&&!r.isDestroyed||this.parasite.rules.organic){let e=new RadialTileFinder(s.map.tiles,s.map.mapBounds,t,{width:1,height:1},1,1,e=>0<s.map.terrain.getPassableSpeed(e,this.parasite.rules.speedType,this.parasite.isInfantry(),i)&&!s.map.terrain.findObstacles({tile:e,onBridge:i},this.parasite).length);a=e.getNextTile();if(!a)return this.parasite.deathType=DeathType.None,s.destroyObject(this.parasite,{player:r.owner,obj:r}),void this.uninfest();t=a}this.parasite.onBridge=i,this.parasite.position.subCell=this.parasite.isInfantry()?r.position.subCell:0,this.parasite.zone=s.map.getTileZone(t,!i),this.parasite.position.tileElevation=i?s.map.tileOccupation.getBridgeOnTile(t).tileElevation:0,this.parasite.resetGuardModeToIdle(),s.unlimboObject(this.parasite,t,!0)}else this.parasite.deathType=DeathType.None,s.destroyObject(this.parasite,{player:r.owner,obj:r});this.uninfest()}}destroyParasite(e,t){this.parasite&&(this.parasite.deathType=DeathType.None,t.destroyObject(this.parasite,e),this.uninfest())}dispose(){this.gameObject=void 0}}class ShipSubmergeChangeEvent{constructor(e){this.target=e,this.type=EventType.ShipSubmergeChange}}const SUBMERGE_PENALTY_SECONDS=5;class SubmergibleTrait{constructor(){this.isActive=!1}isSubmerged(){return this.isActive}setCooldown(e){this.cooldownTicks=e}[NotifyTick_NotifyTick.onTick](e,t){this.isActive||e.parasiteableTrait?.isInfested()||(e.attackTrait&&e.attackTrait.attackState!==AttackState.Idle&&!e.moveTrait.isMoving()?this.cooldownTicks=Math.max(this.cooldownTicks??0,SUBMERGE_PENALTY_SECONDS*GameSpeed.BASE_TICKS_PER_SECOND):this.cooldownTicks??(this.cooldownTicks=Math.floor(60*t.rules.general.cloakDelay*GameSpeed.BASE_TICKS_PER_SECOND)),0<this.cooldownTicks&&this.cooldownTicks--,this.cooldownTicks<=0&&(this.isActive=!0,t.events.dispatch(new ShipSubmergeChangeEvent(e))))}[NotifyDamage.onDamage](e,t){this.emerge(e,t)}emerge(e,t){this.isActive&&(this.isActive=!1,this.cooldownTicks=void 0,t.events.dispatch(new ShipSubmergeChangeEvent(e)))}}class HoverBobTrait{constructor(){this.prevHoverBobLeptons=0,this.spawnTick=0}[NotifySpawn.onSpawn](e,t){this.setBaseElevation(e,t),this.spawnTick=t.currentTick}[NotifyTileChange_NotifyTileChange.onTileChange](e,t,i,r){r&&(this.prevHoverBobLeptons=0,this.setBaseElevation(e,t))}setBaseElevation(e,t){e.position.tileElevation=(e.onBridge?t.map.tileOccupation.getBridgeOnTile(e.tile)?.tileElevation??0:0)+Coords.worldToTileHeight(t.rules.general.hover.height)}[NotifyTick_NotifyTick.onTick](e,t){var i=this.computeHoverBobLeptons(t.currentTick,t.rules.general.hover),t=i-this.prevHoverBobLeptons;this.prevHoverBobLeptons=i;i=Coords.tileHeightToWorld(e.position.tileElevation);e.position.tileElevation=Coords.worldToTileHeight(i+t)}computeHoverBobLeptons(e,t){e=(e-this.spawnTick)/GameSpeed.BASE_TICKS_PER_SECOND/(60*t.bob);return.1*t.height*GameMath.sin(2*e*Math.PI)}}class TilterTrait{constructor(){this.tilt={pitch:0,yaw:0}}[NotifySpawn.onSpawn](e){this.tilt=this.computeTilt(e.tile.rampType)}[NotifyTileChange_NotifyTileChange.onTileChange](e){this.tilt=this.computeTilt(e.tile.rampType)}computeTilt(e){let t,i;return 0===e||17<=e?t=i=0:i=e<=4?(t=25,-90*e):(t=25,225-(e-1)%4*90),{pitch:t,yaw:i}}}const ROCKING_TICKS=34;class Vehicle_Vehicle extends Techno_Techno{get isMoving(){return this.moveTrait.isMoving()}static factory(e,t,i,r,s){let a=new this(e,t,i);return a.isSinker=!t.underwater&&(t.weight>=r.general.shipSinkingWeight||!t.naval),a.moveTrait=new MoveTrait(a,s),a.traits.add(a.moveTrait),t.crashable&&(a.crashableTrait=new CrashableTrait(a),a.traits.add(a.crashableTrait)),t.crewed&&(a.crewedTrait=new CrewedTrait,a.traits.add(a.crewedTrait)),t.harvester&&(a.harvesterTrait=new HarvesterTrait(t.storage),a.traits.add(a.harvesterTrait)),t.passengers&&(a.transportTrait=new TransportTrait(a),a.traits.add(a.transportTrait),t.gunner&&(a.gunnerTrait=new GunnerTrait,a.traits.add(a.gunnerTrait))),t.turret&&(a.turretTrait=new TurretTrait,a.traits.add(a.turretTrait)),t.consideredAircraft&&!t.landable||a.traits.add(new DockableTrait),t.parasiteable&&(a.parasiteableTrait=new ParasiteableTrait(a),a.traits.add(a.parasiteableTrait)),t.naval&&t.underwater&&(a.submergibleTrait=new SubmergibleTrait,a.traits.add(a.submergibleTrait)),t.locomotor===LocomotorType.Hover&&a.traits.add(new HoverBobTrait),[LocomotorType.Vehicle,LocomotorType.Chrono].includes(t.locomotor)&&i.isVoxel&&(a.tilterTrait=new TilterTrait,a.traits.add(a.tilterTrait)),a}constructor(e,t,i){super(ObjectType.Vehicle,e,t,i),this.direction=0,this.spinVelocity=0,this.crateBonuses=new CrateBonuses,this.turretNo=0,this.onBridge=!1,this.isSinker=!1,this.isFiring=!1,this.zone=t.naval?ZoneType.Water:ZoneType.Ground}isUnit(){return!0}isVehicle(){return!0}getUiName(){if(this.gunnerTrait){var e=this.armedTrait.getSpecialWeaponIndex(),t=this.gunnerTrait.getUiNameForIfvMode(e,this.transportTrait?.units[0]?.name),e="name:"+this.name;return t?`{${t}} {${e}}`:e}return super.getUiName()}update(e){this.rocking&&(this.rocking.ticksLeft--,this.rocking.ticksLeft||(this.rocking=void 0)),super.update(e)}applyRocking(e,t){this.rules.consideredAircraft||(this.rocking={ticksLeft:this.rocking?.ticksLeft??ROCKING_TICKS,facing:e,factor:t})}}class AirportBoundTrait{constructor(e){this.airportNames=e}findAvailableAirport(e){return[...e.owner.buildings].find(e=>e.dockTrait&&this.airportNames.includes(e.name)&&0<e.dockTrait.getAvailableDockCount())}}class SpawnLinkTrait{setParent(e){this.parent=e}getParent(){return this.parent}[NotifyTick_NotifyTick.onTick](r,s){if(this.parent&&r.attackTrait&&r.primaryWeapon){let e=this.parent.attackTrait?.currentTarget,t=r.unitOrderTrait.getCurrentTask(),i=new RangeHelper(s.map.tileOccupation);var a=this.parent.armedTrait?.getWeapons().find(e=>e.rules.spawner);r.ammo&&!(e&&r.attackTrait.currentTarget?e.equals(r.attackTrait.currentTarget):e===r.attackTrait.currentTarget||!e&&this.parent.isUnit()&&(this.parent.unitOrderTrait.getCurrentTask()instanceof MoveTask||this.parent.unitOrderTrait.getCurrentTask()instanceof AttackTask))&&(!e||a&&i.isInWeaponRange(this.parent,e.obj??e.tile,a,s.rules))?e&&r.primaryWeapon.targeting.canTarget(e.obj,e.tile,s,!0,!1)?!t||t instanceof MoveTask?(r.unitOrderTrait.cancelAllTasks(),r.unitOrderTrait.addTask(r.attackTrait.createAttackTask(s,e.obj,e.tile,r.primaryWeapon,{force:!0}))):r.attackTrait.attackState!==AttackState.Idle&&t.requestTargetUpdate(e):t?t instanceof MoveTask||t.cancel():this.tryMoveToParent(r,this.parent,s):this.tryMoveToParent(r,this.parent,s)}}tryMoveToParent(t,i,r){if(t.tile!==i.tile){let e=t.unitOrderTrait.getCurrentTask();e?e instanceof MoveTask&&e.updateTarget(i.tile,!!i.isUnit()&&i.onBridge):t.unitOrderTrait.addTask(new MoveTask(r,i.tile,!!i.isUnit()&&i.onBridge,{closeEnoughTiles:0,strictCloseEnough:!0}))}}}class MissileSpawnTrait{setWarhead(e){return this.warhead=e,this}setDamage(e){return this.damage=e,this}setLauncher(e){return this.launcher=e,this}[NotifyDestroy.onDestroy](e,t){this.warhead&&this.damage&&this.launcher&&this.warhead.detonate(t,this.damage,e.tile,e.tileElevation,e.position.worldPosition,e.zone,CollisionType.None,t.createTarget(void 0,e.tile),{player:e.owner,obj:this.launcher,weapon:void 0})}dispose(){this.launcher=void 0}}class Aircraft_Aircraft extends Techno_Techno{get direction(){return this.yaw}set direction(e){this.yaw=e}get isMoving(){return this.moveTrait.isMoving()}static factory(e,t,i,r,s){let a=new this(e,t,i);return a.rules.airportBound&&a.rules.dock.length&&(a.airportBoundTrait=new AirportBoundTrait(a.rules.dock),a.traits.add(a.airportBoundTrait)),a.rules.missileSpawn||(a.crashableTrait=new CrashableTrait(a),a.traits.add(a.crashableTrait)),a.rules.spawned&&(a.rules.missileSpawn?(a.missileSpawnTrait=new MissileSpawnTrait,a.traits.add(a.missileSpawnTrait)):(a.spawnLinkTrait=new SpawnLinkTrait,a.traits.add(a.spawnLinkTrait))),a.moveTrait=new MoveTrait(a,s),a.traits.add(a.moveTrait),t.dock.length&&a.traits.add(new DockableTrait),t.landable&&e!==r.general.paradrop.paradropPlane||a.traits.add(new UnlandableTrait),t.parasiteable&&(a.parasiteableTrait=new ParasiteableTrait(a),a.traits.add(a.parasiteableTrait)),a}constructor(e,t,i){super(ObjectType.Aircraft,e,t,i),this.pitch=0,this.yaw=0,this.roll=0,this.onBridge=!1,this.zone=ZoneType.Ground,this.crateBonuses=new CrateBonuses}isUnit(){return!0}isAircraft(){return!0}}class UnitOrderTrait{constructor(e){this.gameObject=e,this.orders=[],this.queuedOrders=new Set,this.tasks=[],this.taskRunner=new TaskRunner}[NotifyTick_NotifyTick.onTick](i,e){if(i.isSpawned){var r=this.hasTasks(),t=this.tasks.find(e=>!e.isCancelling());if(r&&this.taskRunner.tick(this.tasks,i),i.isSpawned){var s,a=this.orders.length;if(a&&(!r||!t)){let e,t=!1;for(;e=this.orders[0];){if(e.isValid()&&e.isAllowed()&&((s=e.process())&&(this.queuedOrders.has(e)&&(this.tasks.push(new WaitTicksTask(5)),this.tasks.push(new CallbackTask(()=>{i.resetGuardModeToIdle()}))),this.tasks.push(...s),r||this.taskRunner.tick(this.tasks,i)),t=!0),this.orders.shift(),this.queuedOrders.delete(e),!i.isSpawned)return;if(this.waypointPath&&(this.currentWaypoint?(this.cleanupWaypoint(this.currentWaypoint,this.waypointPath),this.currentWaypoint=this.currentWaypoint?.next):this.currentWaypoint=this.waypointPath.waypoints[0],this.currentWaypoint||this.cleanupWaypointPath()),t)break}}!a&&!r&&this.waypointPath&&this.currentWaypoint&&(this.cleanupWaypoint(this.currentWaypoint,this.waypointPath),this.cleanupWaypointPath());let e=t;for(;e?.useChildTargetLines;){var n=e.children.find(e=>!e.isCancelling());if(!n)break;e=n}this.targetLinesTask!==e&&(this.targetLinesTask=e,this.targetLinesConfig=e?.getTargetLinesConfig(this.gameObject))}}}[NotifyOwnerChange.onChange](){this.clearOrders(),this.cancelAllTasks()}[NotifyTeleport.onBeforeTeleport](e,t,i,r){i&&!r&&(this.clearOrders(),this.tasks.length=0)}addOrder(t,e=!1){!1!==t.onAdd(this.tasks,e)?(e||(this.clearOrders(),this.tasks=this.tasks.filter(e=>e.status!==TaskStatus.NotStarted),this.tasks.forEach(e=>e.cancel())),this.orders.push(t),e&&this.queuedOrders.add(t),this.gameObject.traits.filter(NotifyOrder).forEach(e=>{e[NotifyOrder.onPush](this.gameObject,t.orderType)})):this.targetLinesTask=void 0}clearOrders(){this.orders.length=0,this.queuedOrders.clear(),this.currentWaypoint&&this.waypointPath&&this.cleanupWaypoint(this.currentWaypoint,this.waypointPath),this.cleanupWaypointPath(),this.gameObject.resetGuardModeToIdle()}unmarkNextQueuedOrder(){this.orders.length&&this.queuedOrders.delete(this.orders[0])}hasTasks(){return!!this.tasks.length}isIdle(){return!this.orders.length&&!this.tasks.length}getCurrentTask(){return this.tasks[0]}cancelAllTasks(){this.tasks.forEach(e=>e.cancel())}addTask(e){this.tasks.push(e)}addTasks(...e){e.forEach(e=>this.addTask(e))}addTaskToFront(e){this.tasks.unshift(e)}addTaskNext(e){this.tasks.splice(1,0,e)}getTasks(){return[...this.tasks]}dispose(){this.clearOrders(),this.tasks.length=0,this.gameObject=void 0}cleanupWaypointPath(){this.waypointPath&&(this.waypointPath.units.splice(this.waypointPath.units.indexOf(this.gameObject),1),this.waypointPath.units.length||(this.waypointPath.waypoints.forEach(e=>e.next=void 0),this.waypointPath.waypoints.length=0),this.waypointPath=void 0),this.currentWaypoint=void 0}cleanupWaypoint(t,e){if(!e.units.find(e=>e!==this.gameObject&&(e.unitOrderTrait.currentWaypoint??e.unitOrderTrait.waypointPath?.waypoints[0])===t)&&!e.waypoints.find(e=>e.next===t)){var i=e.waypoints.indexOf(t);if(-1===i)throw new Error("Given waypoint not found in waypoint path");e.waypoints.splice(i,1)}}}const rampHeights=[[0,0,0,0],[0,0,1,1],[1,0,0,1],[1,1,0,0],[0,1,1,0],[0,0,0,1],[1,0,0,0],[0,1,0,0],[0,0,1,0],[1,0,1,1],[1,1,0,1],[1,1,1,0],[0,1,1,1],[1,0,1,2],[2,1,0,1],[1,2,1,0],[0,1,2,1],[1,0,1,0],[0,1,0,1],[1,0,1,0],[0,1,0,1]];class ObjectPosition{get onPositionChange(){return this._onPositionChange.asEvent()}get worldPosition(){return this._worldPosition}get tile(){return this._tile}set tile(e){var t=!!this._tile&&e!==this._tile;(this._tile=e)&&(this.updateWorldPosition(e,this._tileOffset),this._onPositionChange.dispatch(this,{tileChanged:t}))}get tileElevation(){return void 0===this._tileElevation?(void 0===this._computedTileElevation&&(this._computedTileElevation=this.computeTileElevationFromWorldPos()),this._computedTileElevation):this._tileElevation}set tileElevation(e){this._absoluteElevation=void 0,this._tileElevation=e,this._tile&&(this.updateWorldPosition(this._tile,this._tileOffset),this._onPositionChange.dispatch(this,{tileChanged:!1}))}get subCell(){if(!this._tileOffset.x&&!this._tileOffset.y)return 0;var e=Math.sign(this._tileOffset.x/Coords.LEPTONS_PER_TILE-.5),t=Math.sign(this._tileOffset.y/Coords.LEPTONS_PER_TILE-.5);return e&&t?t+1+(e+1)/2+1:0}set subCell(e){this._tileOffset=this.computeSubCellOffset(e),this.desiredSubCell=e,this._tile&&(this.updateWorldPosition(this._tile,this._tileOffset),this._onPositionChange.dispatch(this,{tileChanged:!1}))}constructor(e,t){this.tiles=e,this.tileOccupation=t,this._worldPosition=new Vector3_Vector3,this._tileOffset=new Vector2,this._centerOffset=new Vector2,this.desiredSubCell=0,this._tileElevation=0,this._onPositionChange=new EventDispatcher}getTileOffset(){return this._tileOffset.clone()}setTileOffset(e){this._tileOffset.copy(e),this._tile&&(this.updateWorldPosition(this._tile,this._tileOffset),this._onPositionChange.dispatch(this,{tileChanged:!1}))}setCenterOffset(e){this._centerOffset.copy(e),this._tile&&(this.updateWorldPosition(this._tile,this._tileOffset),this._onPositionChange.dispatch(this,{tileChanged:!1}))}getMapPosition(){if(this._tile)return new Vector2(this._tile.rx*Coords.LEPTONS_PER_TILE+this._tileOffset.x+this._centerOffset.x,this._tile.ry*Coords.LEPTONS_PER_TILE+this._tileOffset.y+this._centerOffset.y)}getBridgeBelow(){return this._tile?.onBridgeLandType?this.tileOccupation.getBridgeOnTile(this._tile):void 0}moveToTileCell(e,t=0){if(!this._tile)throw new Error("Tile is not set");var i=e!==this._tile;this._tile=e,this._tileOffset=this.computeSubCellOffset(t),this.desiredSubCell=t,this.updateWorldPosition(e,this._tileOffset),this._onPositionChange.dispatch(this,{tileChanged:i})}moveToTileCoords(e,t,i=!1){var r=Math.floor(e),s=Math.floor(t),a=!this._tile||this._tile.rx!==r||this._tile.ry!==s;if(a){let e=this.tiles.getByMapCoords(r,s);if(!e){if(!i)throw new RangeError(`Attempted move to a non-existent tile: [${r},${s}]`);e=this.tiles.getPlaceholderTile(r,s)}this._tile=e}this._tileOffset.set((e-r)*Coords.LEPTONS_PER_TILE,(t-s)*Coords.LEPTONS_PER_TILE),this.updateWorldPosition(this._tile,this._tileOffset),this._onPositionChange.dispatch(this,{tileChanged:a})}moveToLeptons(e,t=!1){this.moveToTileCoords(e.x/Coords.LEPTONS_PER_TILE,e.y/Coords.LEPTONS_PER_TILE,t)}moveByLeptons(e,t,i=!1){if(!this._tile)throw new Error("Tile is not set");this.moveToTileCoords(this._tile.rx+(this._tileOffset.x+e)/Coords.LEPTONS_PER_TILE,this._tile.ry+(this._tileOffset.y+t)/Coords.LEPTONS_PER_TILE,i)}moveByLeptons3(e,t=!1){var i=this._worldPosition.y;this.moveByLeptons(e.x,e.z,t),this.setAbsoluteElevationWorld(i+e.y)}setAbsoluteElevationWorld(e){this._absoluteElevation=e,this._tileElevation=void 0,this._tile&&(this.updateWorldPosition(this._tile,this._tileOffset),this._onPositionChange.dispatch(this,{tileChanged:!1}))}computeSubCellOffset(e){let t={width:0,height:0};var i;e&&(i=(e-1)%2*2-1,r=2*Math.floor((e-1)/2)-1,t={width:i*Coords.LEPTONS_PER_TILE/4,height:r*Coords.LEPTONS_PER_TILE/4});var r=Coords.LEPTONS_PER_TILE/2;return new Vector2(r+t.width,r+t.height)}interpolateRampHeight(e,t,i){var r=rampHeights[i],s=r[1],i=r[0];return s*(1-e)*(1-t)+r[2]*e*(1-t)+i*(1-e)*t+r[3]*e*t}updateWorldPosition(t,i){var e=i.x+this._centerOffset.x,r=i.y+this._centerOffset.y,s=e/Coords.LEPTONS_PER_TILE,i=r/Coords.LEPTONS_PER_TILE;let a;if(void 0!==this._tileElevation){let e=0;0!==t.rampType&&(e=this.interpolateRampHeight(s,i,t.rampType)),a=Coords.tileHeightToWorld(t.z+e+this._tileElevation)}else a=this._absoluteElevation;this._worldPosition.set(t.rx*Coords.LEPTONS_PER_TILE+e,a,t.ry*Coords.LEPTONS_PER_TILE+r),void 0===this._tileElevation&&(this._computedTileElevation=this.computeTileElevationFromWorldPos())}computeTileElevationFromWorldPos(){if(!this._tile)return 0;var e=roundToDecimals(Coords.worldToTileHeight(this._worldPosition.y),14),t=(this._tileOffset.x+this._centerOffset.x)/Coords.LEPTONS_PER_TILE,i=(this._tileOffset.y+this._centerOffset.y)/Coords.LEPTONS_PER_TILE;let r=0;return 0!==this._tile.rampType&&(r=this.interpolateRampHeight(t,i,this._tile.rampType)),e-this._tile.z-r}clone(){let e=new ObjectPosition(this.tiles,this.tileOccupation);return e._worldPosition=this._worldPosition.clone(),e._tile=this._tile,e._tileOffset=this._tileOffset.clone(),e._centerOffset=this._centerOffset.clone(),e._tileElevation=this._tileElevation,e._absoluteElevation=this._absoluteElevation,e._computedTileElevation=this._computedTileElevation,e}}const AIR_DETONATION_Z_THRESH=1.5,WALL_HEIGHT=2,UNIT_HEIGHT=1.1;class CollisionHelper{constructor(e){this.tileOccupation=e}checkCollisions(e,t,i){var r,s=e.tile;let a,n,o;for(r of this.tileOccupation.getObjectsOnTile(s))r.isOverlay()&&r.isBridge()&&(a=r),r.isOverlay()&&r.wallTrait&&(o=r),r.isTechno()&&!r.isDestroyed&&(n=r);if(i.walls){if(e.tileElevation<=WALL_HEIGHT&&s.landType===LandType.Wall)return{type:CollisionType.Wall,target:o};if(i.units&&n?.tile===s&&(!n.isUnit()||n.zone===ZoneType.Ground)&&e.tileElevation<=UNIT_HEIGHT&&i.units(n.owner))return{type:CollisionType.Wall,target:n}}if(i.shore&&s.landType!==LandType.Water)return{type:CollisionType.Shore};if(i.ground&&e.tileElevation<0)return{type:CollisionType.Ground};var l=e.tileElevation+s.z,h=t.tileElevation+t.tile.z;if(a?.isHighBridge()){var c=a.tile.z+a.tileElevation;if(c<h&&l<=c||h<c&&c-1<=l)return h<c?{type:CollisionType.UnderBridge,target:a}:{type:CollisionType.OnBridge,target:a}}else if(a?.isLowBridge()&&i.shore)return{type:CollisionType.UnderBridge,target:a};if(i.cliffs){t=s.z-t.tile.z;if(e.tileElevation<0&&4<=t)return{type:CollisionType.Cliff}}return{type:CollisionType.None}}computeDetonationZone(e,t,i){let r=this.tileOccupation.getBridgeOnTile(e);return i===CollisionType.None&&t>AIR_DETONATION_Z_THRESH+(r?.tileElevation??0)?ZoneType.Air:r&&t>AIR_DETONATION_Z_THRESH||e.terrainType!==TerrainType.Water||r?.isLowBridge()?ZoneType.Ground:ZoneType.Water}}const CRUISING_ELEVATION_TILE_THRESH=2,CRUISING_ELEVATION_BASE=2,CRUISING_ELEVATION_TILES=3,HOMING_ELEVATION_Z_SPEED=.25,LIMBO_TELEPORT_TICKS=10,MAX_OVERSHOOT_TILES=2;!function(e){e[e.Travel=0]="Travel",e[e.Impact=1]="Impact",e[e.Detonation=2]="Detonation"}(ProjectileState=ProjectileState||{});class Projectile extends GameObject{get fromObject(){return this._fromObject}set fromObject(e){(this._fromObject=e)&&e.veteranTrait&&!e.isDestroyed&&(this.veteranDamageMult=e.veteranTrait.getVeteranDamageMultiplier())}get rot(){return this.fromWeapon.rules.isSonic?ObjectRules.iniRotToDegsPerTick(this.iniRot):this.rules.rot}get iniRot(){return this.fromWeapon.rules.isSonic?10:this.rules.iniRot}static factory(e,t,i,r){return new this(e,t,i,r)}constructor(e,t,i,r){super(ObjectType.Projectile,e,t,i),this.tileOccupation=r,this.state=ProjectileState.Travel,this.detonationTimer=0,this.collisionType=CollisionType.None,this.direction=0,this.zone=ZoneType.Air,this.isShrapnel=!1,this.isNuke=!1,this.baseDamageMultiplier=1,this.veteranDamageMult=1,this.snapToTarget=!1,this.targetLockLost=!1,this.limboTravelTicks=0,this.homingTravelDistance=0,this.homingTravelTicks=0,this.velocity=new Vector3_Vector3,this.sonicVisitedObjects=new Map,this.collisionHelper=new CollisionHelper(r)}onSpawn(a){var e;if(super.onSpawn(a),this.initialSelfPosition=this.position.worldPosition.clone(),!this.target.obj||this.fromWeapon.type===WeaponType.DeathWeapon||this.fromWeapon.rules.limboLaunch||!this.isHoming()&&this.fromWeapon.speed===Number.POSITIVE_INFINITY||this.rules.inaccurate||this.rules.arcing||this.rules.flakScatter||0<(e=this.computeBaseDamage(a))&&(e=this.fromWeapon.warhead.computeDamage(e,this.target.obj,a),this.target.obj.healthTrait?.projectDamage(e)),a.afterTick(()=>{let e=new RangeHelper(this.tileOccupation);var t=e.distance2(this.target.getWorldCoords(),this)/Coords.LEPTONS_PER_TILE;this.initialTileDistToTarget=t,this.maxSpeed=this.computeMaxSpeed(this.fromWeapon.speed,t,a.rules.audioVisual.gravity)}),this.isHoming()){if(1===this.iniRot&&(this.homingMoveDir=this.target.getWorldCoords().clone().sub(this.position.worldPosition)),this.fromObject?.isAircraft()&&this.rules.isAntiGround&&!this.rules.isAntiAir){let e=this.target.obj;!e?.isVehicle()||e.isDestroyed||e.veteranLevel!==VeteranLevel.Elite||e.unitOrderTrait.hasTasks()||e.unitOrderTrait.addTask(new ScatterTask(a))}}else if(this.rules.vertical){let e=this.position.clone();e.tileElevation=this.fromWeapon.warhead.rules.nukeMaker?Coords.worldToTileHeight(this.fromWeapon.projectileRules.detonationAltitude):0,this.aimPoint=e.worldPosition.clone()}else{let s=this.target.getWorldCoords().clone();a.afterTick(()=>{let e=this.target.getWorldCoords().clone().sub(s);var t=e.length()>Coords.LEPTONS_PER_TILE;let i=t?s:this.target.obj?.isUnit()&&this.target.obj.moveTrait.velocity.length()&&isFinite(this.maxSpeed)?this.computeAimPointVersusMovingTarget(this.target.obj,this.maxSpeed,this.position.worldPosition,a.map):this.target.getWorldCoords().clone();this.aimPoint=i,this.snapToTarget=!t&&isFinite(this.maxSpeed)&&!this.fromWeapon.warhead.rules.sonic,(this.rules.inaccurate||this.rules.flakScatter)&&(this.adjustAimForBallisticScatter(a,i),this.snapToTarget=!1),!t&&this.rules.arcing&&(this.rules.inaccurate?(this.overshootTiles=this.calculateInaccurateBallisticOvershoot(a),this.snapToTarget=!1):this.target.obj?.isVehicle()&&this.target.obj.moveTrait.isMoving()&&(this.overshootTiles=this.calculateBallisticOvershootVsMoving(a,this.target.obj),this.overshootTiles&&(this.snapToTarget=!1)));let r=i.clone().sub(this.position.worldPosition);r.length()<this.fromWeapon.speed&&this.update(a)})}}adjustAimForBallisticScatter(e,t){let i=e.rules.combatDamage.ballisticScatter,r;r=this.rules.flakScatter?(this.rules.inviso&&(i*=2),e.generateRandom()*i):i/2+e.generateRandom()*(i/2);let s=r*Coords.LEPTONS_PER_TILE;this.rules.flakScatter&&(n=t.clone().sub(this.initialSelfPosition).length(),s*=n/(this.fromWeapon.range*Coords.LEPTONS_PER_TILE));var a=rotateVec2(new Vector2(s,0),e.generateRandomInt(0,360)),n=Coords.vecWorldToGround(t).add(a).multiplyScalar(1/Coords.LEPTONS_PER_TILE).floor();e.map.tiles.getByMapCoords(n.x,n.y)&&t.add(new Vector3_Vector3(a.x,0,a.y))}calculateBallisticOvershootVsMoving(e,t){let i=this.target.getWorldCoords().clone().sub(this.initialSelfPosition);var r=angleDegBetweenVec2(Coords.vecWorldToGround(i),Coords.vecWorldToGround(t.moveTrait.velocity)),t=(90<r?180-r:r)/90,r=i.length()/Coords.LEPTONS_PER_TILE,t=t*r/5;return e.generateRandom()<=t?Math.min(1,r/5)*MAX_OVERSHOOT_TILES:0}calculateInaccurateBallisticOvershoot(e){return e.generateRandom()<=.5?MAX_OVERSHOOT_TILES:0}update(o){if(void 0!==this.maxSpeed)if(super.update(o),this.state!==ProjectileState.Impact){var s=this.velocity.clone(),l=this.position.clone();if(this.velocity.set(0,0,0),this.fromWeapon.rules.limboLaunch){if(!this.fromObject)throw new Error("Limbo launch projectile must be fired from a unit");if(this.fromObject.isDestroyed)return void o.destroyObject(this)}var h=this.updateSpeed(this.maxSpeed);this.speed=h;let n=this.target.getWorldCoords();if(this.lastTargetLockPosition&&(this.targetLockLost||n.clone().sub(this.lastTargetLockPosition).length()>=Coords.LEPTONS_PER_TILE)?(n=this.lastTargetLockPosition,this.targetLockLost=!0):this.lastTargetLockPosition=n.clone(),this.isHoming()){if(this.target.obj?.isUnit()&&(this.target.obj.isDestroyed||this.target.obj.isCrashing||!this.target.obj.isSpawned)&&(this.fromWeapon.rules.limboLaunch||this.homingTravelDistance>=2*Coords.LEPTONS_PER_TILE))return void this.detonate(o);if(this.homingMoveDir||(u=FacingUtil.toMapCoords(this.direction),this.homingMoveDir=new Vector3_Vector3(u.x,0,u.y),this.fromObject?.isAircraft()&&(this.homingMoveDir.y=-9999999,this.homingMoveDir.normalize())),this.fromWeapon.rules.limboLaunch){if(!this.targetLockLost){if(this.limboTravelTicks>LIMBO_TELEPORT_TICKS)return this.position.moveToLeptons(this.target.obj.position.getMapPosition()),this.position.tileElevation=this.target.obj.position.tileElevation,void this.detonate(o);this.limboTravelTicks++}}else if(!this.isInHomingRange(n,o))return void this.detonate(o);let e=new RangeHelper(this.tileOccupation);var c=Math.floor(e.distance2(n,this)/Coords.LEPTONS_PER_TILE),u=c>CRUISING_ELEVATION_TILE_THRESH&&1<this.iniRot;let t=n.clone().sub(this.position.worldPosition),i=0;this.homingTravelTicks<this.rules.courseLockDuration||(u?(rotateVec3Towards(this.homingMoveDir,new Vector3_Vector3(t.x,this.homingMoveDir.y,t.z),this.rot),this.rules.level||(c=clamp(Math.floor(this.initialTileDistToTarget)-1,0,CRUISING_ELEVATION_BASE)+clamp(c-CRUISING_ELEVATION_TILE_THRESH,0,CRUISING_ELEVATION_TILES),d=this.tileOccupation.getBridgeOnTile(this.tile)?.tileElevation??0,(d=c-(this.position.tileElevation-d))&&(p=HOMING_ELEVATION_Z_SPEED+6/this.iniRot*.1,i=Coords.tileHeightToWorld(Math.sign(d)*Math.min(Math.abs(d),p))))):rotateVec3Towards(this.homingMoveDir,t,this.rot)),this.direction=FacingUtil.fromMapCoords(new Vector2(this.homingMoveDir.x,this.homingMoveDir.z));var d=t.length(),p=Math.min(d,h);this.homingTravelDistance+=p,this.homingTravelTicks++;let r=!1,s=CollisionType.None,a;if(d>=Coords.LEPTONS_PER_TILE/4){let e=this.homingMoveDir.clone().setLength(p);i&&(e.y+=i),p===h&&this.velocity.copy(e);var g=e.clone().add(this.position.worldPosition);o.map.mapBounds.isWithinHardBounds(g)?this.position.moveByLeptons3(e):r=!0;var m=this.checkObstacles(l,o);if(s=m.type,a=m.target,s)r=!0;else{let e=n.clone().sub(this.position.worldPosition);var y=e.length();d<y&&y<2*Coords.LEPTONS_PER_TILE&&(r=!0)}}else this.position.moveByLeptons3(t),r=!0;if(r){if(a&&s===CollisionType.Wall){let e=a.position.worldPosition;this.position.moveByLeptons3(e.clone().sub(this.position.worldPosition))}this.collisionType=s,this.detonate(o,s)}}else{let t=this.aimPoint.clone().sub(this.position.worldPosition);this.rules.vertical||(this.direction=FacingUtil.fromMapCoords(new Vector2(t.x,t.z))),this.rules.arcing&&(t.y=0);g=Math.min(t.length(),h);if(t.setLength(g),this.rules.arcing){let e=Coords.vecWorldToGround(this.position.worldPosition.clone().sub(this.initialSelfPosition).add(t));var m=this.aimPoint.clone().sub(this.initialSelfPosition),a=e.length(),d=Coords.vecWorldToGround(m).length(),y=m.y,m=o.rules.audioVisual.gravity;d&&(t.y=(y/d*h+m/2*d/h)*a/h-m*(a/h)*(a/h)/2+this.initialSelfPosition.y-this.position.worldPosition.y)}let e=!1;a=t.clone().add(this.position.worldPosition);o.map.isWithinHardBounds(a)?this.position.moveByLeptons3(t):e=!0;let i=CollisionType.None,r;if(1<=g?(g!==h&&!this.overshootTiles||this.velocity.copy(t),l=this.checkObstacles(l,o),i=l.type,r=l.target,(i||g<h)&&(e=!0)):e=!0,e){if(i){if(r&&i===CollisionType.Wall){let e=r.isBuilding()?Coords.tile3dToWorld(r.tile.rx+.5,r.tile.ry+.5,r.tile.z):r.position.worldPosition;this.position.moveByLeptons3(e.clone().sub(this.position.worldPosition))}}else if(this.overshootTiles){var T=Coords.vecWorldToGround(s).setLength(this.overshootTiles*Coords.LEPTONS_PER_TILE);if(rotateVec2(T,o.generateRandomInt(-45,45)),a=Coords.vecGroundToWorld(T).add(this.position.worldPosition),!o.map.isWithinHardBounds(a))return void o.unspawnObject(this);this.position.moveByLeptons(T.x,T.y)}else if(this.snapToTarget&&!this.targetLockLost){if(!o.map.isWithinHardBounds(n))return void o.unspawnObject(this);this.position.moveByLeptons3(n.clone().sub(this.position.worldPosition))}this.collisionType=i,this.isNuke?(this.state=ProjectileState.Impact,this.detonationTimer=2.5*GameSpeed.BASE_TICKS_PER_SECOND):this.detonate(o,i)}}let e=this.fromWeapon.warhead;if(e.rules.sonic){var t,i,T=11/30*Coords.LEPTONS_PER_TILE,T=this.position.worldPosition.clone().add(this.velocity.clone().setLength(T)),T=Coords.vecWorldToGround(T).multiplyScalar(1/Coords.LEPTONS_PER_TILE).floor(),r=o.map.tiles.getByMapCoords(T.x,T.y);if(r&&r!==this.fromObject?.tile){var f,v=o.map.getTileZone(r);for(f of o.map.getGroundObjectsOnTile(r))if((!f.isUnit()||!f.onBridge)&&(!f.isTechno()||!f.rules.typeImmune||f.owner!==this.fromPlayer||f.name!==this.fromObject?.name)&&(!f.isAircraft()||!f.rules.spawned)&&e.canDamage(f,r,v)){let e=this.sonicVisitedObjects.get(f)??new Set;e.add(r),this.sonicVisitedObjects.set(f,e)}}for([t,i]of this.sonicVisitedObjects)for(var b of i)o.map.tileOccupation.isTileOccupiedBy(b,t)&&t.isSpawned&&(b=this.fromWeapon.rules.ambientDamage*this.veteranDamageMult*this.baseDamageMultiplier,b=e.computeDamage(b,t,o),e.inflictDamage(b,t,{player:this.fromPlayer,weapon:this.fromWeapon,obj:this.fromObject},o,t!==this.target.obj))}}else 0<this.detonationTimer?this.detonationTimer--:this.detonate(o,this.collisionType)}isHoming(){return!!this.rot&&!this.rules.arcing}isInHomingRange(t,i){let r=!0,s=this.target.obj;if(s?.isUnit()&&this.fromObject){let e=new RangeHelper(this.tileOccupation);i=e.computeWeaponRangeVsTarget(this.fromObject,s,this.fromWeapon,i.rules).range;this.fromWeapon.rules.limboLaunch?r=e.isInRange3(this.initialSelfPosition,t,0,i+.5):(t=s.moveTrait.velocity.length())&&(this.fromObject.rules.movementZone===MovementZone.Fly?5<this.speed/t&&(r=e.isInRange2(this.initialSelfPosition,this.position.worldPosition,0,i)):isFinite(this.fromWeapon.speed)&&3.5<this.fromWeapon.speed/s.rules.speed&&(r=e.isInRange3(this.initialSelfPosition,this.position.worldPosition,0,i)))}return r}updateSpeed(e){let t;return t=this.isHoming()||this.rules.vertical?void 0===this.speed?Math.min(e,this.rules.acceleration):Math.min(e,this.speed+this.rules.acceleration):e,t}computeMaxSpeed(e,t,i){let r=e;return this.rules.arcing&&(r*=(1+i/6)/2,t=Math.floor(t),r*=t<=8?1:1+t/8*.5),this.fromWeapon.warhead.rules.sonic&&(r=Math.ceil(t*Coords.LEPTONS_PER_TILE/21)),r}checkObstacles(e,t){return this.fromWeapon.rules.limboLaunch?{type:CollisionType.None}:this.collisionHelper.checkCollisions(this.position,e,{cliffs:this.rules.subjectToCliffs,ground:this.isHoming(),shore:this.rules.level,walls:this.rules.subjectToWalls,units:!this.rules.inaccurate&&(e=>this.fromPlayer!==e&&!t.alliances.areAllied(this.fromPlayer,e))})}computeBaseDamage(e){var t=this.fromWeapon,i=t.warhead;let r=t.rules.damage;t.type===WeaponType.DeathWeapon&&i.rules.ivanBomb&&(r=e.rules.combatDamage.ivanDamage);let s=r*this.baseDamageMultiplier;return t.type===WeaponType.DeathWeapon&&this.fromObject&&(s*=this.fromObject.rules.deathWeaponDamageModifier),s*=this.veteranDamageMult,s}detonate(n,e=CollisionType.None){var i=this.fromWeapon;let r=i.warhead;var t,s=this.zone=this.collisionHelper.computeDetonationZone(this.tile,this.tileElevation,e);let o=this.tile;i.type===WeaponType.DeathWeapon&&r.rules.ivanBomb&&(r=new Warhead(n.rules.getWarhead(n.rules.combatDamage.ivanWarhead)));let a=this.computeBaseDamage(n);n.destroyObject(this),this.state=ProjectileState.Detonation;let l=this.target.obj,h=!1;if(r.rules.parasite&&l?.isUnit()&&o===l.tile&&r.canDamage(l,o,s))if(l.isInfantry())a=Number.POSITIVE_INFINITY;else if(l.parasiteableTrait&&this.fromObject?.isUnit()){if(!(this.fromWeapon instanceof Weapon))throw new Error("Projectile with parasite warhead must have a weapon reference");l.parasiteableTrait.infest(this.fromObject,this.fromWeapon),h=!0}let c=!0;if(h&&(c=!1),r.rules.sonic&&(c=!1),r.rules.ivanBomb&&(c=!1,!l?.isTechno()||!l.tntChargeTrait||l.tntChargeTrait.hasCharge()||l.isDestroyed||l.warpedOutTrait.isInvulnerable()||(t=n.rules.combatDamage.ivanTimedDelay,l.tntChargeTrait.setCharge(t,n.currentTick,{player:this.fromPlayer,obj:this.fromObject}))),r.rules.bombDisarm&&(c=!1,l?.isTechno()&&l.tntChargeTrait?.hasCharge()&&!l.isDestroyed&&l.tntChargeTrait.removeCharge()),r.rules.mindControl&&(c=!1,this.fromObject&&!this.fromObject.isDestroyed&&l?.isTechno()&&l.mindControllableTrait&&!l.mindControllableTrait?.isActive()&&!n.areFriendly(l,this.fromObject)&&r.canDamage(l,o,s)&&!l.invulnerableTrait.isActive()&&this.fromObject.mindControllerTrait.control(l,n)),r.rules.temporal&&(c=!1,this.fromObject&&!this.fromObject.isDestroyed&&l?.isTechno()&&r.canDamage(l,o,s)&&!l.invulnerableTrait.isActive()&&(r.inflictDamage(0,l,{player:this.fromPlayer,weapon:i,obj:this.fromObject},n),this.fromObject.temporalTrait.updateTarget(l,i,n))),r.rules.makesDisguise&&(c=!1,this.fromObject&&!this.fromObject.isDestroyed&&(this.fromObject.isInfantry()||this.fromObject.isVehicle())&&l?.isUnit()&&l.type===this.fromObject.type&&this.fromObject.disguiseTrait?.disguiseAs(l,this.fromObject,n)),r.rules.electricAssault&&(this.fromObject?.isUnit()&&!this.fromObject.isDestroyed&&l?.isBuilding()&&!l.isDestroyed&&l.overpoweredTrait&&l.owner===this.fromPlayer&&l.overpoweredTrait.chargeFrom(this.fromObject),c=!1),c&&r.detonate(n,a,o,this.tileElevation,this.position.worldPosition,s,e,this.target,{player:this.fromPlayer,weapon:i,obj:this.fromObject},this.isShrapnel?SpecialWarheadType.Shrapnel:SpecialWarheadType.None,this.impactAnim),r.rules.nukeMaker){let e;e=this.fromObject?(u=Weapon.factory(Weapon.NUKE_PAYLOAD_NAME,WeaponType.Primary,this.fromObject,n.rules),n.createProjectile(u.projectileRules.name,this.fromObject,u,this.target,!1)):n.createLooseProjectile(Weapon.NUKE_PAYLOAD_NAME,this.fromPlayer,this.target),e.isNuke=!0,e.impactAnim="NUKEBALL";var u=this.target.tile;e.position.moveToTileCoords(u.rx+.5,u.ry+.5),e.position.tileElevation=this.position.tileElevation,n.spawnObject(e,u)}if(this.rules.shrapnelCount&&this.rules.shrapnelWeapon&&((this.target.obj?!this.target.obj.isBuilding():n.map.getGroundObjectsOnTile(this.target.tile).some(e=>e.isTerrain()||e.isTechno())&&!i.projectileRules.isAntiAir)||this.isShrapnel)){let t=n.rules.getWeapon(this.rules.shrapnelWeapon);var d,p=n.rules.getProjectile(t.projectile);let i=this.rules.shrapnelCount,r=new RangeHelper(n.map.tileOccupation),e=new RadialTileFinder(n.map.tiles,n.map.mapBounds,o,{width:1,height:1},1,t.range,e=>r.isInTileRange(o,e,t.minimumRange,t.range)),s=new Set;for(;0<Math.floor(i);){var g,m=e.getNextTile();if(!m)break;for(g of n.map.tileOccupation.getObjectsOnTileByLayer(m,p.isAntiAir?LayerType.Air:LayerType.Ground).filter(e=>n.isValidTarget(e)&&(e.isTerrain()||e.isTechno()&&e.owner!==this.fromPlayer&&!n.alliances.areAllied(e.owner,this.fromPlayer)&&!(e.isInfantry()&&e.stance===StanceType.Paradrop))))if(!s.has(g)&&(s.add(g),i=Math.max(0,i-1-(g.isTechno()?.5:0)),Math.floor(i)<=0))break}for(d of s){var y=n.createTarget(d.isTerrain()?void 0:d,d.tile);this.createShrapnel(n,y,t.name)}i=Math.floor(i);let a=new RandomTileFinder(n.map.tiles,n.map.mapBounds,o,t.range,n,e=>r.isInTileRange(o,e,t.minimumRange,t.range));for(let e=0;e<i;e++){var T=a.getNextTile();if(!T)break;T=n.createTarget(void 0,T);this.createShrapnel(n,T,t.name)}}if(i.rules.limboLaunch&&!h&&this.fromObject?.isUnit()){let s=this.fromObject;r.rules.parasite&&(this.target.obj.isVehicle()||this.target.obj?.isAircraft())&&this.target.obj.parasiteableTrait&&(this.target.obj.parasiteableTrait.beingBoarded=!1);let t,a;i=s.rules.movementZone===MovementZone.Fly;if(i)t=o,a=!1;else{let i=this.target.obj.isUnit()&&this.target.obj.tile.onBridgeLandType&&!this.target.obj.onBridge?void 0:n.map.tileOccupation.getBridgeOnTile(o),r=new MovePositionHelper(n.map),e=new RadialTileFinder(n.map.tiles,n.map.mapBounds,o,{width:1,height:1},0,1,e=>{var t=n.map.tileOccupation.getBridgeOnTile(e);return 0<n.map.terrain.getPassableSpeed(e,s.rules.speedType,s.isInfantry(),!!t)&&r.isEligibleTile(e,t,i,o)&&(e===o||!n.map.terrain.findObstacles({tile:e,onBridge:i},s).length)});t=e.getNextTile(),a=!!t?.onBridgeLandType}t?(!i&&this.target.obj.isUnit()&&(s.onBridge=a,s.position.tileElevation=a?n.map.tileOccupation.getBridgeOnTile(t)?.tileElevation??0:0),n.unlimboObject(s,t),s.isInfantry()&&(s.position.subCell=this.target.obj.position.subCell),s.direction=this.direction):s.owner.removeOwnedObject(s)}}createShrapnel(e,t,i){let r=e.createLooseProjectile(i,this.fromPlayer,t);r.isShrapnel=!0,r.veteranDamageMult=this.veteranDamageMult,r.position.moveToLeptons(this.position.getMapPosition()),r.position.tileElevation=this.position.tileElevation,e.spawnObject(r,r.position.tile)}computeAimPointVersusMovingTarget(t,i,e,r){let s=t.position.worldPosition,a=s.clone();var n=i,i=t.moveTrait.velocity.length();if(n<3*i)return s.clone();let o=TargetUtil.computeInterceptPoint(e,n,s,t.moveTrait.velocity);if(o.length()){let e=o.clone().sub(s);n=e.length(),i=i,n=i?Math.ceil(n/i):0;if(o=s.clone().add(e.setLength(n*i)),r.isWithinHardBounds(o))if(t.zone!==ZoneType.Air){o.multiplyScalar(1/Coords.LEPTONS_PER_TILE);let e=t.position.clone();e.moveToTileCoords(o.x,o.z),a=e.worldPosition}else a=o;else a=s}return a.clone()}}const DEPLOY_FIRE_DELAY_TICKS=15;!function(e){e[e.None=0]="None",e[e.PreparingToFire=1]="PreparingToFire",e[e.FiringUp=2]="FiringUp",e[e.Firing=3]="Firing"}(DeployFireState=DeployFireState||{});class DeployerTrait{constructor(e){this.gameObject=e,this.deployed=!1,this.deployFireDelay=0,this.deployFireState=DeployFireState.None,this.fireUpDelay=0,this.deployFireCount=0}isDeployed(){return this.deployed}setDeployed(t){var e=this.deployed;if((this.deployed=t)!==e){let e=this.gameObject;e.isInfantry()&&(e.stance=t?StanceType.Deployed:StanceType.None),t?(this.deployFireState=DeployFireState.PreparingToFire,t=this.gameObject.armedTrait?.getDeployFireWeapon(),this.deployWeapon=t?.rules.areaFire?t:void 0,this.deployFireDelay=DEPLOY_FIRE_DELAY_TICKS+((t===e.primaryWeapon?e.secondaryWeapon:e.primaryWeapon)?.getCooldownTicks()??0),this.deployFireCount=0,this.undeployDelay=this.gameObject.rules.undeployDelay||void 0):(this.deployFireState===DeployFireState.FiringUp&&(e.isFiring=!1),this.deployFireState=DeployFireState.None,this.deployWeapon=void 0)}}toggleDeployed(){this.setDeployed(!this.isDeployed())}[NotifyTick_NotifyTick.onTick](e,t){if(void 0!==this.undeployDelay&&(0<this.undeployDelay&&this.undeployDelay--,this.undeployDelay<=0&&[DeployFireState.None,DeployFireState.PreparingToFire].includes(this.deployFireState)))return this.undeployDelay=void 0,void this.setDeployed(!1);if(this.deployWeapon&&this.deployFireState!==DeployFireState.None){if(this.deployFireState===DeployFireState.PreparingToFire){if(0<this.deployFireDelay--||0===e.ammo)return;if(0<this.computeDeployFireCooldown(this.deployWeapon,t))return;this.fireUpDelay=Math.max(1,e.art.fireUp),this.deployFireState=DeployFireState.FiringUp}if(this.deployFireState===DeployFireState.FiringUp){if(e.isFiring=!0,0<this.fireUpDelay--)return;this.deployFireState=DeployFireState.Firing}var i;this.deployFireState===DeployFireState.Firing&&(e.isFiring=!1,i=e.onBridge?t.map.tileOccupation.getBridgeOnTile(e.tile):void 0,this.deployWeapon.fire(t.createTarget(i,e.tile),t),this.deployFireCount++,(this.deployWeapon===e.primaryWeapon?e.secondaryWeapon:e.primaryWeapon)?.resetCooldown(),this.deployWeapon.rules.fireOnce?(this.deployFireState=DeployFireState.None,this.deployWeapon=void 0):this.deployFireState=DeployFireState.PreparingToFire)}}computeDeployFireCooldown(t,i){if(t.rules.radLevel&&t.rules.areaFire){var r=this.gameObject.tile,r=i.mapRadiationTrait.getRadSiteLevel(r);if(!r)return 0;i=i.rules.radiation;let e=Math.max(0,r*i.radDurationMultiple-i.radLevelDelay);return 1===this.deployFireCount&&(i=i.radDurationMultiple*t.rules.radLevel,e=Math.max(0,e-Math.floor(.25*i))),e}return t.getCooldownTicks()}getHash(){return this.deployed?1:0}debugGetState(){return{deployed:this.deployed}}dispose(){this.gameObject=void 0}}(NotifyHealthChange=NotifyHealthChange||{}).onChange=Symbol();class InflictDamageEvent{constructor(e,t,i,r,s){this.target=e,this.attacker=t,this.damageHitPoints=i,this.currentHealth=r,this.prevHealth=s,this.type=EventType.InflictDamage}}(NotifyHealthChange_NotifyHealthChange=NotifyHealthChange_NotifyHealthChange||{}).onChange=Symbol(),function(e){e[e.Green=0]="Green",e[e.Yellow=1]="Yellow",e[e.Red=2]="Red"}(HealthLevel=HealthLevel||{});class HealthChangeEvent{constructor(e,t,i){this.target=e,this.currentHealth=t,this.prevHealth=i,this.type=EventType.HealthChange}}const MIN_PROJECTED_HIT_POINTS=-30,PROJECTED_HEALTH_DECAY_FRAMES=4;class HealthTrait{get health(){return this._computedHealth}set health(e){this.setHitPoints(0<e?Math.max(1,Math.floor(e*this.maxHitPoints/100)):0),this.projectedHitPoints=this.hitPoints}get level(){return this.health>100*this.conditionYellow?HealthLevel.Green:this.health>100*this.conditionRed?HealthLevel.Yellow:HealthLevel.Red}constructor(e,t,i,r){this.maxHitPoints=e,this.gameObject=t,this.conditionYellow=i,this.conditionRed=r,this.setHitPoints(e),this.projectedHitPoints=this.hitPoints}setHitPoints(e){if(e!==Math.floor(e))throw new Error(`Value ${e} is not an integer`);this.hitPoints=clamp(e,0,this.maxHitPoints),this._computedHealth=this.hitPoints/this.maxHitPoints*100}getHitPoints(){return this.hitPoints}getProjectedHitPoints(){return this.projectedHitPoints}inflictDamage(t,i,r){var e=this.hitPoints,s=this.health;this.applyHitPoints(e-t,r),e!==this.hitPoints&&0<t&&(this.gameObject.traits.filter(NotifyDamage).forEach(e=>{e[NotifyDamage.onDamage](this.gameObject,r,t,i)}),r.events.dispatch(new InflictDamageEvent(this.gameObject,i,t,this.health,s)))}healBy(e,i,r){if(e<0)throw new Error("Can't heal by negative value "+e);if(this.hitPoints<this.maxHitPoints){var s=this.hitPoints;this.applyHitPoints(this.hitPoints+e,r),this.projectedHitPoints=this.hitPoints;let t=this.hitPoints-s;this.gameObject.traits.filter(NotifyHeal).forEach(e=>{e[NotifyHeal.onHeal]?.(this.gameObject,r,t,i)})}}healToFull(i,r){if(this.hitPoints<this.maxHitPoints){var e=this.hitPoints;this.applyHitPoints(this.maxHitPoints,r),this.projectedHitPoints=this.hitPoints;let t=this.hitPoints-e;this.gameObject.traits.filter(NotifyHeal).forEach(e=>{e[NotifyHeal.onHeal]?.(this.gameObject,r,t,i)})}}applyHitPoints(e,t){let i=this.health;this.setHitPoints(e),i!==this.health&&(t.traits.filter(NotifyHealthChange).forEach(e=>{e[NotifyHealthChange.onChange](this.gameObject,t,i)}),this.gameObject.traits.filter(NotifyHealthChange_NotifyHealthChange).forEach(e=>{e[NotifyHealthChange_NotifyHealthChange.onChange](this.gameObject,t,i)}),t.events.dispatch(new HealthChangeEvent(this.gameObject,this.health,i)))}projectDamage(e){if(e<0)throw new Error("Projected damage must be positive");this.projectedHitPoints=Math.max(MIN_PROJECTED_HIT_POINTS,this.projectedHitPoints-e)}[NotifyTick_NotifyTick.onTick](e,t){t.currentTick%PROJECTED_HEALTH_DECAY_FRAMES==0&&(this.projectedHitPoints=Math.min(this.projectedHitPoints+1,this.hitPoints))}getHash(){return this.hitPoints}debugGetState(){return{hitPoints:this.hitPoints}}dispose(){this.gameObject=void 0}}class BridgeTrait{constructor(e){this.bridges=e,this.needsImageUpdate=!1,this.dominoHandled=!1}[NotifyDamage.onDamage](){this.needsImageUpdate=!0}[NotifyTick_NotifyTick.onTick](e){this.needsImageUpdate&&(this.needsImageUpdate=!1,this.bridges.handlePieceHealthChange(this.bridges.getPieceAtTile(e.tile)))}[NotifyDestroy.onDestroy](s,a,n){var e=this.bridges.getPieceAtTile(s.tile);this.dominoHandled||this.bridges.findDominoPieces(e).filter(e=>!e.obj.isDestroyed).forEach(e=>{e.obj.traits.get(BridgeTrait).dominoHandled=!0,a.destroyObject(e.obj,n)});let t=a.map.tileOccupation.calculateTilesForGameObject(s.tile,s);t.forEach(e=>{let i=getLandType(e.terrainType),r=a.rules.getLandRules(i);a.map.getGroundObjectsOnTile(e).forEach(e=>{if(e.isUnit()&&(e.onBridge||e.moveTrait.reservedPathNodes.some(e=>e.onBridge===s))&&!e.isDestroyed)if(s.isLowBridge()&&0<r.getSpeedModifier(e.rules.speedType)||e.isInfantry()&&e.stance===StanceType.Paradrop){e.onBridge&&(e.onBridge=!1,e.zone=getZoneType(i));for(var t of e.moveTrait.reservedPathNodes)t.onBridge===s&&(t.onBridge=void 0);e.moveTrait.currentWaypoint?.onBridge===s&&(e.moveTrait.currentWaypoint.onBridge=void 0)}else e.isInfantry()&&(e.infDeathType=InfDeathType.None),a.destroyObject(e,n,!0)})})}}const SPAWN_RADIUS=2,SPAWN_BAILS=1,SPAWN_INITIAL_BAILS=3;!function(e){e[e.Idle=0]="Idle",e[e.Spawning=1]="Spawning"}(SpawnStatus=SpawnStatus||{});class TiberiumTreeTrait{constructor(e){this.rules=e,this.ticksSinceLastSpawn=0,this.cooldownTicks=Math.floor(1/this.rules.animationProbability),this.status=SpawnStatus.Idle}[NotifyTick_NotifyTick.onTick](e,t){this.status=SpawnStatus.Idle,this.ticksSinceLastSpawn++>this.cooldownTicks&&(this.ticksSinceLastSpawn=0,this.status=SpawnStatus.Spawning,this.spawnTiberium(e.tile,t))}spawnTiberium(r,s){for(let i=1;i<=SPAWN_RADIUS;i++){let e=new RadialTileFinder(s.map.tiles,s.map.mapBounds,r,{width:1,height:1},i,i,e=>TiberiumTrait.canBePlacedOn(e,s.map));var a=e.getNextTile();if(a){var n=OreSpread.calculateOverlayId(TiberiumType.Ore,a);if(void 0===n)throw new Error("Expected an overlayId");let e=s.createObject(ObjectType.Overlay,s.rules.getOverlayName(n));return e.overlayId=n,e.value=SPAWN_INITIAL_BAILS,void s.spawnObject(e,a)}e=new RadialTileFinder(s.map.tiles,s.map.mapBounds,r,{width:1,height:1},i,i,e=>e.landType===LandType.Tiberium);let t;for(;!t;){var o=e.getNextTile();if(!o)break;t=s.map.getObjectsOnTile(o).find(e=>e.isOverlay()&&e.isTiberium()&&e.traits.get(TiberiumTrait).getBailCount()+SPAWN_BAILS<=TiberiumTrait.maxBails)}if(t)return void t.traits.get(TiberiumTrait).spawnBails(SPAWN_BAILS)}}}class AutoRepairTrait{constructor(e=!1){this.freeRepair=e,this.disabled=!0,this.cooldownTicks=0,this.healLeftover=0}isDisabled(){return this.disabled}setDisabled(e){this.disabled=e}[NotifyTick_NotifyTick.onTick](t,i){if(!this.isDisabled())if(100===t.healthTrait.health&&this.setDisabled(!0),this.cooldownTicks<=0){var r=i.rules.general.repair,s=t.isInfantry()?r.iRepairRate:t.isBuilding()?r.repairRate:r.uRepairRate;this.cooldownTicks+=GameSpeed.BASE_TICKS_PER_SECOND*s*60;var a=t.isInfantry()?r.iRepairStep:r.repairStep,s=this.freeRepair?0:r.repairPercent;let e;s?(r=s*t.purchaseValue/t.healthTrait.maxHitPoints,(s=Math.min(t.owner.credits,Math.max(1,Math.floor(r*a))))?(e=r?s/r:a,t.owner.credits-=s):(e=0,this.setDisabled(!0))):e=a,e&&(e+=this.healLeftover,e=Math.min(t.healthTrait.maxHitPoints-t.healthTrait.getHitPoints(),e),e&&(a=Math.floor(e),this.healLeftover=e-a,a&&t.healthTrait.healBy(a,t,i)))}else this.cooldownTicks--}[NotifyOwnerChange.onChange](){this.setDisabled(!0)}}(NotifyTargetDestroy=NotifyTargetDestroy||{}).onDestroy=Symbol();class UnitPromoteEvent{constructor(e){this.target=e,this.type=EventType.UnitPromote}}class SelfHealingTrait{constructor(){this.cooldownTicks=0}[NotifyTick_NotifyTick.onTick](e,t){100!==e.healthTrait.health&&(this.cooldownTicks<=0?(this.cooldownTicks+=GameSpeed.BASE_TICKS_PER_SECOND*t.rules.general.repair.repairRate*60,e.healthTrait.healBy(1,e,t)):this.cooldownTicks--)}}class ArmedTrait{constructor(e,t){this.gameObject=e,this.rules=t,this.specialWeaponIndex=0;t=e.veteranLevel===VeteranLevel.Elite;e.rules.weaponCount?(this.selectSpecialWeapon(0,t),this.guardWeaponRangeOverride=this.primaryWeapon?.range):this.selectStandardWeapons(t)}selectStandardWeapons(e=!1){var t=this.gameObject,i=e&&t.rules.elitePrimary||t.rules.primary;i?(s=e?t.art.elitePrimaryFireFlh:t.art.primaryFireFlh,this.primaryWeapon=Weapon.factory(i,WeaponType.Primary,t,this.rules,s)):this.primaryWeapon=void 0;var r,s=e&&t.rules.eliteSecondary||t.rules.secondary;s?(r=e?t.art.eliteSecondaryFireFlh:t.art.secondaryFireFlh,this.secondaryWeapon=Weapon.factory(s,WeaponType.Secondary,t,this.rules,r)):this.secondaryWeapon=void 0,(t.explodes||t.crashableTrait)&&(r=t.rules.deathWeapon||!!t.crashableTrait&&this.secondaryWeapon?.rules.name||this.primaryWeapon?.rules.name||this.rules.combatDamage.deathWeapon,this.deathWeapon=Weapon.factory(r,WeaponType.DeathWeapon,t,this.rules))}selectSpecialWeapon(e,t=!1){let i=this.gameObject;var r=i.rules.weaponCount;if(r<1)throw new Error(`Object "${i.name}" doesn't support special weapons`);if(r-1<e)throw new RangeError(`Weapon index ${e} out of bounds (max ${r}) for object `+i.name);r=t&&i.rules.getEliteWeaponAtIndex(e)||i.rules.getWeaponAtIndex(e);if(!r)throw new Error(`Missing weapon at index ${e} for object "${i.name}"`);t=i.art.getSpecialWeaponFlh(e);this.primaryWeapon=Weapon.factory(r,WeaponType.Primary,i,this.rules,t),this.secondaryWeapon=void 0,this.specialWeaponIndex=e,this.deathWeapon=this.primaryWeapon.rules.suicide?Weapon.factory(i.rules.deathWeapon||this.primaryWeapon.name,WeaponType.DeathWeapon,i,this.rules):void 0}toggleEliteWeapons(e){this.gameObject.rules.weaponCount?this.selectSpecialWeapon(this.specialWeaponIndex,e):this.selectStandardWeapons(e)}getSpecialWeaponIndex(){return this.specialWeaponIndex}computeGuardScanRange(t){var e=this.guardWeaponRangeOverride??[this.primaryWeapon,this.secondaryWeapon].filter(e=>e===t||e?.rules.neverUse).reduce((e,t)=>Math.max(e,t.range),0),e=Math.max(e,this.gameObject.rules.guardRange);return Math.min(15,2*e-1)}getDeployFireWeapon(){if(this.gameObject.rules.deployFire)return this.gameObject.rules.deployFireWeapon===WeaponType.Primary?this.primaryWeapon:this.secondaryWeapon}isEquippedWithWeapon(e){return[this.primaryWeapon,this.secondaryWeapon].includes(e)}getWeapons(){return[this.primaryWeapon,this.secondaryWeapon].filter(isNotNullOrUndefined)}[NotifyTick_NotifyTick.onTick](){this.primaryWeapon&&this.primaryWeapon.tick(),this.secondaryWeapon&&this.secondaryWeapon.tick()}[NotifyDestroy.onDestroy](t,e,i){!this.deathWeapon||i?.weapon?.warhead.rules.temporal||t.crashableTrait&&!t.isCrashing||i?.obj?.isVehicle()&&i.weapon?.rules.suicide&&i.obj.transportTrait?.units.find(e=>e===t)||this.deathWeapon.fire(e.createTarget(t,t.tile),e)}dispose(){this.gameObject=void 0,this.primaryWeapon=void 0,this.secondaryWeapon=void 0,this.deathWeapon=void 0}}class SensorsTrait{}class VeteranTrait{constructor(e,t){this.gameObject=e,this.veteranRules=t,this.veteranLevel=VeteranLevel.None,this.xp=0,this.promotionThresh=e.rules.cost*t.veteranRatio+1}[NotifyTargetDestroy.onDestroy](e,t,i,r){e.isDestroyed&&!e.isCrashing||t.isTechno()&&(t.rules.dontScore||t.rules.insignificant||(i&&(i.warhead.rules.temporal||i.warhead.rules.parasite&&e.rules.organic)||!r.areFriendly(e,t))&&(this.veteranLevel>=this.veteranRules.veteranCap||this.gainXP(t.rules.cost*(t.veteranLevel+1))&&this.handlePromotion(e,r)))}setRelativeXP(e){this.gainXP(Math.floor(e*this.promotionThresh))}gainXP(e){if(this.xp+=e,this.xp>=this.promotionThresh){var t=Math.min(this.veteranLevel+Math.floor(this.xp/this.promotionThresh),this.veteranRules.veteranCap),e=t-this.veteranLevel;if(e)return this.xp-=e*this.promotionThresh,this.setVeteranLevel(t),!0}return!1}promote(e,t){e=Math.min(this.veteranLevel+e,this.veteranRules.veteranCap);e-this.veteranLevel&&(this.setVeteranLevel(e),this.handlePromotion(this.gameObject,t))}isMaxLevel(){return this.veteranLevel===this.veteranRules.veteranCap}isElite(){return this.veteranLevel===VeteranLevel.Elite}setVeteranLevel(e){this.veteranLevel=e,this.veteranLevel===VeteranLevel.Elite&&this.gameObject.armedTrait?.toggleEliteWeapons(!0)}handlePromotion(e,t){this.hasVeteranAbility(VeteranAbility.SELF_HEAL)&&(e.traits.find(SelfHealingTrait)||t.addObjectTrait(e,new SelfHealingTrait)),this.hasVeteranAbility(VeteranAbility.CLOAK)&&(e.cloakableTrait||(e.cloakableTrait=new CloakableTrait(e,t.rules.general.cloakDelay),t.addObjectTrait(e,e.cloakableTrait))),this.hasVeteranAbility(VeteranAbility.EXPLODES)&&(e.explodes||(e.explodes=!0,e.armedTrait||(e.armedTrait=new ArmedTrait(e,t.rules),t.addObjectTrait(e,e.armedTrait)))),this.hasVeteranAbility(VeteranAbility.RADAR_INVISIBLE)&&(e.radarInvisible||(e.radarInvisible=!0)),this.hasVeteranAbility(VeteranAbility.SENSORS)&&(e.sensorsTrait||(e.sensorsTrait=new SensorsTrait,t.addObjectTrait(e,e.sensorsTrait))),e.isInfantry()&&this.hasVeteranAbility(VeteranAbility.FEARLESS)&&e.suppressionTrait?.disable(),this.hasVeteranAbility(VeteranAbility.C4)&&(e.c4||(e.c4=!0)),this.hasVeteranAbility(VeteranAbility.GUARD_AREA)&&(e.defaultToGuardArea||(e.defaultToGuardArea=!0,e.unitOrderTrait.isIdle()&&e.resetGuardModeToIdle())),this.hasVeteranAbility(VeteranAbility.CRUSHER)&&(e.crusher||(e.crusher=!0)),t.events.dispatch(new UnitPromoteEvent(e))}getVeteranSightMultiplier(){return this.getVeteranAbilityMultiplier(VeteranAbility.SIGHT)}getVeteranSpeedMultiplier(){return this.getVeteranAbilityMultiplier(VeteranAbility.FASTER)}getVeteranArmorMultiplier(){return this.getVeteranAbilityMultiplier(VeteranAbility.STRONGER)}getVeteranDamageMultiplier(){return this.getVeteranAbilityMultiplier(VeteranAbility.FIREPOWER)}getVeteranRofMultiplier(){return this.getVeteranAbilityMultiplier(VeteranAbility.ROF)}hasVeteranAbility(e){return this.veteranLevel===VeteranLevel.Veteran&&this.gameObject.rules.veteranAbilities.has(e)||this.veteranLevel>=VeteranLevel.Elite&&this.gameObject.rules.eliteAbilities.has(e)}getVeteranAbilityMultiplier(e){let t=1;return(this.veteranLevel===VeteranLevel.Veteran&&this.gameObject.rules.veteranAbilities.has(e)||this.veteranLevel>=VeteranLevel.Elite&&this.gameObject.rules.eliteAbilities.has(e))&&(t=this.getVeteranRulesMultiplier(e)),t}getVeteranRulesMultiplier(e){switch(e){case VeteranAbility.FASTER:return this.veteranRules.veteranSpeed;case VeteranAbility.STRONGER:return this.veteranRules.veteranArmor;case VeteranAbility.FIREPOWER:return this.veteranRules.veteranCombat;case VeteranAbility.ROF:return this.veteranRules.veteranROF;case VeteranAbility.SIGHT:return this.veteranRules.veteranSight;default:throw new Error("Unhandled VeteranAbility "+e)}}dispose(){this.gameObject=void 0}}class AmmoTrait{constructor(e,t=e){this.maxAmmo=e,this.ammo=t}get ammo(){return this._ammo}set ammo(e){this._ammo=clamp(e,0,this.maxAmmo)}isFull(){return this.ammo===this.maxAmmo}}class ObjectDisguiseChangeEvent{constructor(e){this.target=e,this.type=EventType.ObjectDisguiseChange}}class DisguiseTrait{constructor(){this.isActive=!1,this.cooldownTicks=0}isDisguised(){return this.isActive}getDisguise(){return this.isActive?this.disguisedAs:void 0}hasTerrainDisguise(){return this.getDisguise()?.rules.type===ObjectType.Terrain}disguiseAs(e,t,i){this.disguisedAs={rules:e.rules,owner:e.owner},this.isActive=!0,i.events.dispatch(new ObjectDisguiseChangeEvent(t))}revealDisguise(e,t){this.cooldownTicks=t.rules.general.infantryBlinkDisguiseTime,this.isActive=!1,t.events.dispatch(new ObjectDisguiseChangeEvent(e))}[NotifySpawn.onSpawn](e,t){var i;!this.disguisedAs&&e.rules.permaDisguise&&e.isInfantry()&&e.owner.country&&((i=this.getDefaultInfantryDisguise(e.owner.country.side,t.rules.general))&&(i=t.rules.getObject(i,ObjectType.Infantry),this.disguisedAs={rules:i,owner:e.owner},this.isActive=!0))}getDefaultInfantryDisguise(e,t){switch(e){case SideType.GDI:return t.alliedDisguise;case SideType.Nod:return t.sovietDisguise;case SideType.ThirdSide:return t.thirdDisguise;default:return}}[NotifyTick_NotifyTick.onTick](e,t){e.rules.permaDisguise||(e.attackTrait?.attackState===AttackState.JustFired||e.moveTrait.moveState!==MoveState.Idle?this.revealDisguise(e,t):0<this.cooldownTicks?this.cooldownTicks--:!this.isActive&&e.rules.disguiseWhenStill&&(this.isActive=!0,this.disguisedAs={rules:this.selectRandomMirageDisguise(t),owner:void 0},t.events.dispatch(new ObjectDisguiseChangeEvent(e))))}[NotifyDamage.onDamage](e,t){this.revealDisguise(e,t)}selectRandomMirageDisguise(e){var t=e.rules.general.defaultMirageDisguises;if(!t.length)throw new Error("No default mirage disguises are defined");t=t[e.generateRandomInt(0,t.length-1)];return e.rules.getObject(t,ObjectType.Terrain)}}class InvulnerableTrait{constructor(){this.timer=new Timer}isActive(){return this.timer.isActive()}setActiveFor(e,t){this.timer.setActiveFor(e,t)}[NotifyTick_NotifyTick.onTick](e,t){this.timer.tick(t.currentTick)}}class WarpedOutTrait{constructor(e){this.gameObject=e,this.ticksWhenWarpedOut=!0,this.remainingTicks=0,this.invulnerable=!1}isActive(){return 0<this.remainingTicks}setActive(e,t,i){this.remainingTicks=e?Number.POSITIVE_INFINITY:0,this.invulnerable=t,this.notifyChange(e,i)}setTimed(e,t,i){this.remainingTicks=e,this.invulnerable=t,this.notifyChange(!0,i)}debugSetActive(e){this.remainingTicks=e?Number.POSITIVE_INFINITY:0}notifyChange(t,i){i.traits.filter(NotifyWarpChange).forEach(e=>{e[NotifyWarpChange.onChange](this.gameObject,i,t)}),this.gameObject.traits.filter(NotifyWarpChange_NotifyWarpChange).forEach(e=>{e[NotifyWarpChange_NotifyWarpChange.onChange](this.gameObject,i,t)})}expire(e){this.remainingTicks=0,this.notifyChange(!1,e)}isInvulnerable(){return this.isActive()&&this.invulnerable}[NotifyTick_NotifyTick.onTick](e,t){0<this.remainingTicks&&(this.remainingTicks--,this.remainingTicks<=0&&this.notifyChange(!1,t))}dispose(){this.gameObject=void 0}}class TntChargeTrait{constructor(){this.timer=new Timer}hasCharge(){return this.timer.isActive()}setCharge(e,t,i){this.hasCharge()||(this.timer.setActiveFor(e,t),this.attackerInfo=i)}getChargeOwner(){return this.attackerInfo?.player}removeCharge(){this.timer.reset()}getTicksLeft(){return this.timer.getTicksLeft()}getInitialTicks(){return this.timer.getInitialTicks()}[NotifyTick_NotifyTick.onTick](e,t){this.timer.isActive()&&!0===this.timer.tick(t.currentTick)&&(e.isBuilding()&&e.cabHutTrait&&e.cabHutTrait.demolishBridge(t,this.attackerInfo),this.detonateIvanWarhead(t,e))}[NotifyDestroy.onDestroy](e,t,i){!this.timer.isActive()||i?.weapon?.warhead.rules.ivanBomb||[DeathType.None,DeathType.Temporal,DeathType.Sink].includes(e.deathType)||(this.timer.reset(),this.detonateIvanWarhead(t,e))}detonateIvanWarhead(e,t){var i=e.rules.combatDamage.ivanDamage;let r=new Warhead(e.rules.getWarhead(e.rules.combatDamage.ivanWarhead));var s=t.tile,a=t.tileElevation,n=t.isUnit()?t.zone:e.map.getTileZone(s),o=!!t.isUnit()&&t.onBridge;r.detonate(e,i,s,a,t.isBuilding()?Coords.tile3dToWorld(s.rx+.5,s.ry+.5,s.z+a):t.position.worldPosition,n,o?CollisionType.OnBridge:CollisionType.None,e.createTarget(t,s),{...this.attackerInfo,weapon:void 0},SpecialWarheadType.TntCharge)}}class MindControllableTrait{constructor(e){this.gameObject=e}getOriginalOwner(){return this.prevOwner}isActive(){return!!this.controller}getController(){return this.controller}controlBy(e,t){if(this.controller)throw new Error(`Object "${this.gameObject?.name}" is already mind controlled by "${e.name}"`);this.controller=e,this.prevOwner=this.gameObject.owner,t.changeObjectOwner(this.gameObject,e.owner)}restore(e){this.prevOwner&&(e.changeObjectOwner(this.gameObject,this.prevOwner),this.prevOwner=void 0,this.controller=void 0)}[NotifyUnspawn.onUnspawn](e,t){this.controller&&(this.controller.mindControllerTrait.cleanTarget(e),!e.isDestroyed&&e.limboData&&this.restore(t))}dispose(){this.gameObject=void 0}}class MindControllerTrait{constructor(e,t=1){this.gameObject=e,this.maxCapacity=t,this.targets=[]}isActive(){return 0<this.targets.length}isAtCapacity(){return this.targets.length===this.maxCapacity}getTargets(){return this.targets}control(e,t){if(!this.gameObject)throw new Error("Trait already disposed");if(!e.mindControllableTrait)throw new Error(`Target "${e.name}" cannot be mind controlled`);if(e.isDisposed)throw new Error(`Target "${e.name}" is disposed`);for(e.mindControllableTrait.controlBy(this.gameObject,t),this.targets.push(e);this.targets.length>this.maxCapacity;){let e=this.targets.shift();e.mindControllableTrait.restore(t)}}cleanTarget(e){e=this.targets.indexOf(e);-1!==e&&this.targets.splice(e,1)}[NotifyUnspawn.onUnspawn](e,t){for(var i of this.targets)i.mindControllableTrait.restore(t);this.targets.length=0}dispose(){this.gameObject=void 0}}class TemporalTrait{constructor(e){this.gameObject=e,this.ticksWhenWarpedOut=!0,this.attackers=new Set}[NotifyTick_NotifyTick.onTick](e,t){if(e.attackTrait&&(e.attackTrait.currentTarget&&!e.warpedOutTrait.isActive()||this.releaseCurrentTarget(t)),void 0!==this.eraseTicks)for(var i of this.attackers){var r=i.temporalTrait.currentWeapon;if(!r)throw new Error(`Attacker "${i.name}" is no longer targeting "${e.name}"`);var s=r.rules.damage;if(this.eraseTicks-=s,this.eraseTicks<=0){e.deathType=DeathType.Temporal,t.destroyObject(e,{player:i.owner,obj:i,weapon:r},!0),this.eraseTicks=void 0;break}}}getTarget(){return this.currentTarget}updateTarget(t,e,i){if(this.currentTarget!==t){this.releaseCurrentTarget(i),this.currentTarget=t,this.currentWeapon=e;e=t.temporalTrait.attackers.size;if(t.temporalTrait.attackers.add(this.gameObject),!e){t.warpedOutTrait.setActive(!0,!0,i);let e=t.unitOrderTrait.getCurrentTask();(e&&e instanceof AttackTask||e instanceof MoveTask)&&e.cancel(),t.temporalTrait.eraseTicks=10*t.healthTrait.maxHitPoints}}}releaseCurrentTarget(t){if(this.currentTarget){if(!this.currentTarget.isDisposed){let e=this.currentTarget.temporalTrait.attackers;e.delete(this.gameObject),e.size||(this.currentTarget.warpedOutTrait.expire(t),this.currentTarget.temporalTrait.eraseTicks=void 0)}this.currentTarget=void 0,this.currentWeapon=void 0}}[NotifyDestroy.onDestroy](e,t){this.releaseCurrentTarget(t)}dispose(){this.gameObject=void 0,this.attackers.clear()}}class AirSpawnTrait{constructor(){this.spawns=[],this.storage=[],this.missileLaunches=[],this.nextRegenTicks=[]}get availableSpawns(){return this.storage.length}debugSetStorage(e,t){this.storage.length=t,this.storage.fill(e,0,t)}isLaunchingMissiles(){return 0<this.missileLaunches.length}[NotifySpawn.onSpawn](t,i){var r=i.rules.getObject(t.rules.spawns,ObjectType.Aircraft);for(let e=0;e<t.rules.spawnsNumber;e++)this.pushNewSpawn(r,i,t)}[NotifyUnspawn.onUnspawn](e,t){this.destroySpawns(e,t)}[NotifyDestroy.onDestroy](e,t,i,r){this.destroySpawns(e,t,i,r)}pushNewSpawn(e,t,i){let r=t.createUnitForPlayer(e,i.owner);r.limboData={selected:!1,controlGroup:void 0},e.missileSpawn&&(r.pitch=90*t.rules.general.getMissileRules(e.name).pitchInitial),this.spawns.push(r),this.storage.push(r)}destroySpawns(e,t,i,r){for(var s of this.spawns)s.isDestroyed||(s.isSpawned&&!s.rules.missileSpawn&&s.crashableTrait?s.crashableTrait.crash(i):(s.isSpawned||(s.armedTrait&&(s.armedTrait.deathWeapon=void 0),s.position.tileElevation=e.position.tileElevation,s.zone=e.isUnit()?e.zone:ZoneType.Ground,s.onBridge=!!e.isUnit()&&e.onBridge,s.position.tile=e.tile),t.destroyObject(s,i,r)));this.spawns.length=0,this.storage.length=0,this.missileLaunches.length=0}[NotifyTick_NotifyTick.onTick](s,a){var t;if(this.spawns=this.spawns.filter(e=>!e.isDestroyed),this.missileLaunches=this.missileLaunches.filter(e=>!e.missile.isDestroyed),this.spawns.length<s.rules.spawnsNumber){var i=s.rules.spawnsNumber-this.spawns.length,r=a.rules.getObject(s.rules.spawns,ObjectType.Aircraft);for(let e=0;e<i;e++)r.missileSpawn&&e&&void 0===this.nextRegenTicks[e]?this.nextRegenTicks[e]=this.nextRegenTicks[0]:((t=this.nextRegenTicks)[e]??(t[e]=s.rules.spawnRegenRate),0<this.nextRegenTicks[e]&&this.nextRegenTicks[e]--),this.nextRegenTicks[e]<=0&&this.pushNewSpawn(r,a,s);this.nextRegenTicks=this.nextRegenTicks.filter(e=>0<e)}if(this.storage.length){if(this.nextReloadTicks??(this.nextReloadTicks=s.rules.spawnReloadRate),0<this.nextReloadTicks&&this.nextReloadTicks--,this.nextReloadTicks<=0){for(var e of this.storage)e.ammoTrait&&e.ammoTrait.ammo<e.ammoTrait.maxAmmo&&e.ammoTrait.ammo++;this.nextReloadTicks=s.rules.spawnReloadRate}}else this.nextReloadTicks=void 0;for(let r of this.missileLaunches.slice()){var n=a.rules.general.getMissileRules(r.missile.name);if(r.pauseFrames??(r.pauseFrames=n.pauseFrames),0<r.pauseFrames&&r.pauseFrames--,r.pauseFrames<=0){var o=90*n.pitchFinal,n=90*(n.pitchFinal-n.pitchInitial)/n.tiltFrames;let i=r.missile;if(i.pitch<o)i.pitch=Math.min(o,i.pitch+n);else{i.unitOrderTrait.addTask(new TaskGroup(new MoveTask(a,r.targetTile,!!r.targetBridge),new CallbackTask(()=>{var e,t;i.isDestroyed||(a.unspawnObject(i),i.dispose(),t=Coords.vecGroundToWorld(FacingUtil.toMapCoords(i.direction).multiplyScalar(1)),e=r.targetWorldPos.clone().add(t),t=a.map.getTileZone(r.targetTile),r.warhead.detonate(a,r.damage,r.targetTile,r.targetBridge?.tileElevation??0,e,t,r.targetBridge?CollisionType.OnBridge:CollisionType.None,r.target,{player:i.owner,obj:s,weapon:void 0}))})).setCancellable(!1));n=this.spawns.indexOf(i);if(-1===n)throw new Error("Missile not found in spawns list");this.spawns.splice(n,1),this.missileLaunches.splice(this.missileLaunches.indexOf(r),1)}}}}[NotifyOwnerChange.onChange](e,t,i){for(var r of this.spawns)r.isDestroyed||i.changeObjectOwner(r,e.owner)}[NotifyWarpChange_NotifyWarpChange.onChange](e,t,i){i&&this.removeMissileLaunches(t)}[NotifyTeleport.onBeforeTeleport](e,t,i,r){r||this.removeMissileLaunches(t)}removeMissileLaunches(e){if(this.missileLaunches.length){for(var t of this.missileLaunches){e.unspawnObject(t.missile),t.missile.dispose();t=this.spawns.indexOf(t.missile);if(-1===t)throw new Error("Missile not found in spawns list");this.spawns.splice(t,1)}this.missileLaunches.length=0}}prepareLaunch(r,s,a){if(this.storage.length){let i=this.storage[0];if(!i.ammo)return;if(this.storage.shift(),i.missileSpawnTrait){let e,t;var n=r.veteranTrait?.isElite(),o=a.rules;if(r.rules.spawns===o.general.v3Rocket.type)e=n?o.combatDamage.v3EliteWarhead:o.combatDamage.v3Warhead,t=n?o.general.v3Rocket.eliteDamage:o.general.v3Rocket.damage;else{if(r.rules.spawns!==o.general.dMisl.type)throw new Error(`Unhandled missile type "${r.rules.spawns}"`);e=n?o.combatDamage.dMislEliteWarhead:o.combatDamage.dMislWarhead,t=n?o.general.dMisl.eliteDamage:o.general.dMisl.damage}a=new Warhead(a.rules.getWarhead(e));i.missileSpawnTrait.setDamage(t).setWarhead(a).setLauncher(r),this.missileLaunches.push({missile:i,targetTile:(s.obj?.isUnit()?s.obj:s).tile,targetBridge:s.getBridge(),targetWorldPos:s.getWorldCoords().clone(),target:s,warhead:a,damage:t,pauseFrames:void 0})}else{if(!i.spawnLinkTrait)throw new Error(`Aircraft "${i.name}" must have Spawned=yes to be launchable`);i.spawnLinkTrait.setParent(r)}return i}}storeAircraft(e,t){if(!this.spawns.includes(e))throw new Error(`Object "${e.name}#${e.id}" not found in list of linked spawns`);if(e.limboData)throw new Error(`Object "${e.name}#${e.id}" is already in limbo`);t.limboObject(e,{selected:!1,controlGroup:void 0}),this.storage.push(e)}}class SpawnDebrisTrait{[NotifyCrash.onCrash](e,t){this.handleDestroy(e,t)}[NotifyDestroy.onDestroy](e,t,i){i?.weapon?.warhead.rules.temporal||e.isCrashing||e.deathType!==DeathType.Sink&&e.isSpawned&&this.handleDestroy(e,t)}handleDestroy(e,t){var i,r;(e.isVehicle()||e.isBuilding()||e.isOverlay())&&(i=e.isOverlay()?0:e.rules.minDebris,r=e.isOverlay()?t.rules.general.bridgeVoxelMax:e.rules.maxDebris,0<(r=t.generateRandomInt(i,r))&&this.spawnDebris(e,t,r))}spawnDebris(t,i,r){let s=t.position.getMapPosition();if(i.map.isWithinHardBounds(s)){let e=t.isOverlay()?[]:t.isVehicle()?t.rules.debrisTypes:t.rules.debrisAnims;e.length||(e=i.rules.audioVisual.metallicDebris),e=e.filter(e=>i.rules.hasObject(e,ObjectType.VoxelAnim)||i.art.hasObject(e,ObjectType.Animation)),new Array(r).fill(0).map(()=>e[i.generateRandomInt(0,e.length-1)]).map(e=>i.createObject(ObjectType.Debris,e)).forEach(e=>{e.position.moveToLeptons(s),e.position.tileElevation=t.position.tileElevation,i.spawnObject(e,e.position.tile)})}}}class Debris extends GameObject{static factory(e,t,i,r){return new this(e,t,i,r)}constructor(e,t,i,r){super(ObjectType.Debris,e,t,i),this.age=0,this.direction=0,this.rotationAxis=new Vector3_Vector3,this.angularVelocity=0,this.zone=ZoneType.Air,this.velocity=new Vector3_Vector3,this.collisionHelper=new CollisionHelper(r)}onSpawn(e){super.onSpawn(e),this.direction=e.generateRandomInt(0,359),this.xySpeed=lerp(0,this.rules.maxXYVel,e.generateRandom()),this.zSpeed=lerp(this.rules.minZVel,this.rules.maxZVel||1.5*this.rules.minZVel,e.generateRandom()),this.rotationAxis.set(e.generateRandom(),e.generateRandom(),e.generateRandom()).normalize(),this.angularVelocity=lerp(this.rules.minAngularVelocity,this.rules.maxAngularVelocity,e.generateRandom())}update(t){if(super.update(t),this.age++,this.rules.duration&&this.age>this.rules.duration)return this.velocity.set(0,0,0),void this.detonate(t);--this.zSpeed;var i=FacingUtil.toMapCoords(this.direction).setLength(this.xySpeed);let r=new Vector3_Vector3(i.x,this.zSpeed,i.y);var s=this.position.clone(),i=r.clone().add(this.position.worldPosition);if(t.map.isWithinHardBounds(i)){this.position.moveByLeptons3(r);let e=!1;var{type:i,target:s}=this.collisionHelper.checkCollisions(this.position,s,{cliffs:!0,ground:!0,shore:!1,walls:!0,units:!1});if(i&&(!([CollisionType.Ground,CollisionType.OnBridge].includes(i)&&0<this.rules.elasticity&&t.map.getTileZone(this.tile)!==ZoneType.Water)||Math.abs(this.zSpeed)<1?e=!0:(this.zSpeed=-this.zSpeed*this.rules.elasticity,this.velocity.y=-this.velocity.y*this.rules.elasticity,this.rotationAxis.negate())),e){if(this.velocity.set(0,0,0),s&&i===CollisionType.Wall){let e=s.position.worldPosition;this.position.moveByLeptons3(e.clone().sub(this.position.worldPosition))}this.detonate(t,i)}else this.velocity.copy(r)}else t.unspawnObject(this)}detonate(t,i=CollisionType.None){var e,r=this.rules.warhead?t.rules.getWarhead(this.rules.warhead):void 0,s=this.zone=this.collisionHelper.computeDetonationZone(this.tile,this.tileElevation,i);let a;s===ZoneType.Water?(e=t.rules.combatDamage.splashList,a=e[0]):(e=this.rules.expireAnim)&&t.rules.animationNames.has(e)&&(a=e),this.explodeAnim=a;let n=new AnimTerrainEffect;if(a&&n.spawnSmudges(a,this.tile,t),t.destroyObject(this),r){let e=new Warhead(r);e.detonate(t,this.rules.damage,this.tile,this.tileElevation,this.position.worldPosition,s,i,t.createTarget(void 0,this.tile),void 0,SpecialWarheadType.None,void 0,this.rules.damageRadius||void 0,!0)}}}class ObjectFactory{constructor(e,t,i,r){this.tiles=e,this.tileOccupation=t,this.bridges=i,this.nextObjectId=r}create(e,t,i,r){let s,a;e===ObjectType.Debris?s=i.hasObject(t,ObjectType.VoxelAnim)?(a=r.getObject(t,ObjectType.VoxelAnim),i.getObject(t,ObjectType.VoxelAnim)):(a=r.getAnimation(t),new DebrisRules(ObjectType.Debris,r.getIni().getOrCreateSection(t))):a=e===ObjectType.Projectile?(s=i.getProjectile(t),s.inviso?new ObjectArt(ObjectType.Projectile,s,new IniSection(t)):r.getProjectile(t)):(s=i.getObject(t,e),r.getObject(t,e));let n;switch(e){case ObjectType.Building:n=Building.factory(t,s,i,a,this.tiles,this.bridges);break;case ObjectType.Infantry:n=Infantry_Infantry.factory(t,s,a,this.tileOccupation);break;case ObjectType.Vehicle:n=Vehicle_Vehicle.factory(t,s,a,i,this.tileOccupation);break;case ObjectType.Aircraft:n=Aircraft_Aircraft.factory(t,s,a,i,this.tileOccupation);break;case ObjectType.Terrain:n=Terrain_Terrain.factory(t,s,a);break;case ObjectType.Overlay:n=Overlay_Overlay.factory(t,s,a);break;case ObjectType.Smudge:n=Smudge_Smudge.factory(t,s,a);break;case ObjectType.Projectile:n=Projectile.factory(t,s,a,this.tileOccupation);break;case ObjectType.Debris:n=Debris.factory(t,s,a,this.tileOccupation);break;default:throw new Error("Not implemented")}if(n.id=this.nextObjectId.value++,n.position=new ObjectPosition(this.tiles,this.tileOccupation),n.isUnit()?n.position.subCell=0:n.isBuilding()&&n.position.setCenterOffset(n.getFoundationCenterOffset()),n.isTechno()&&((n.rules.primary||n.rules.secondary||n.rules.weaponCount||n.rules.explodes)&&(n.armedTrait=new ArmedTrait(n,i),n.traits.add(n.armedTrait)),-1!==n.rules.ammo&&(e=n.rules.initialAmmo,n.ammoTrait=new AmmoTrait(n.rules.ammo,-1!==e?e:void 0),n.traits.add(n.ammoTrait)),n.unitOrderTrait=new UnitOrderTrait(n),n.traits.addToFront(n.unitOrderTrait),(n.primaryWeapon||n.secondaryWeapon)&&(n.attackTrait=new AttackTrait(this.tiles,this.tileOccupation),n.traits.add(n.attackTrait)),(n.isInfantry()||n.isVehicle())&&n.rules.deployer&&(n.deployerTrait=new DeployerTrait(n),n.traits.add(n.deployerTrait)),(n.isInfantry()||n.isVehicle())&&n.rules.canDisguise&&(n.disguiseTrait=new DisguiseTrait,n.traits.add(n.disguiseTrait)),n.rules.cloakable&&(n.cloakableTrait=new CloakableTrait(n,i.general.cloakDelay),n.traits.add(n.cloakableTrait)),n.rules.sensors&&(n.sensorsTrait=new SensorsTrait,n.traits.add(n.sensorsTrait)),n.autoRepairTrait=new AutoRepairTrait(!n.isBuilding()),n.traits.add(n.autoRepairTrait),n.rules.trainable&&(n.veteranTrait=new VeteranTrait(n,i.general.veteran),n.traits.add(n.veteranTrait)),n.rules.selfHealing&&n.traits.add(new SelfHealingTrait),n.invulnerableTrait=new InvulnerableTrait,n.traits.add(n.invulnerableTrait),n.warpedOutTrait=new WarpedOutTrait(n),n.traits.add(n.warpedOutTrait),n.temporalTrait=new TemporalTrait(n),n.traits.add(n.temporalTrait),n.rules.bombable&&!n.art.toOverlay&&(n.tntChargeTrait=new TntChargeTrait,n.traits.add(n.tntChargeTrait)),n.rules.immuneToPsionics||n.isBuilding()||(n.mindControllableTrait=new MindControllableTrait(n),n.traits.add(n.mindControllableTrait)),[n.primaryWeapon,n.secondaryWeapon].some(e=>e?.warhead.rules.mindControl)&&(n.mindControllerTrait=new MindControllerTrait(n),n.traits.add(n.mindControllerTrait)),n.rules.spawns&&(n.airSpawnTrait=new AirSpawnTrait,n.traits.add(n.airSpawnTrait)),n.rules.maxDebris&&n.traits.add(new SpawnDebrisTrait)),n.isTechno()||n.isOverlay()||n.isTerrain()){var o=n.isOverlay()&&BridgeOverlayTypes.isBridge(i.getOverlayId(n.name));let e=n.rules.strength;!e&&n.isTerrain()&&(e=i.general.treeStrength),o&&(e=i.combatDamage.bridgeStrength),(e||n.isTechno())&&(n.healthTrait=new HealthTrait(e,n,i.audioVisual.conditionYellow,i.audioVisual.conditionRed),n.traits.add(n.healthTrait)),n.isOverlay()&&o&&(n.bridgeTrait=new BridgeTrait(this.bridges),n.traits.add(n.bridgeTrait),BridgeOverlayTypes.getOverlayBridgeType(i.getOverlayId(n.name))===OverlayBridgeType.Concrete&&n.traits.add(new SpawnDebrisTrait))}return!n.isOverlay()||void 0!==(o=OreOverlayTypes.getOverlayTibType(i.getOverlayId(n.name)))&&(o=i.getTiberium(o),n.traits.add(new TiberiumTrait(n,o))),n.isTerrain()&&n.rules.spawnsTiberium&&n.traits.add(new TiberiumTreeTrait(n.rules)),n.cachedTraits.tick.push(...n.traits.filter(NotifyTick_NotifyTick)),n}}class World{constructor(){this.allObjects=new Map,this._onObjectSpawned=new EventDispatcher,this._onObjectRemoved=new EventDispatcher}get onObjectSpawned(){return this._onObjectSpawned.asEvent()}get onObjectRemoved(){return this._onObjectRemoved.asEvent()}spawnObject(e){if(this.allObjects.has(e.id))throw new Error("Trying to add an already existing object");this.allObjects.set(e.id,e),this._onObjectSpawned.dispatch(this,e)}removeObject(e){if(!this.allObjects.has(e.id))throw new Error("Trying to remove non-existent object");this.allObjects.delete(e.id),this._onObjectRemoved.dispatch(this,e)}hasObjectId(e){return this.allObjects.has(e)}getObjectById(e){if(!this.allObjects.has(e))throw new Error(`Object with id ${e} doesn't exist`);return this.allObjects.get(e)}getAllObjects(){return[...this.allObjects.values()]}}class Node{constructor(e,t){this.id=e,this.data=t,this.neighbors=new Set}addLink(e){this.neighbors.add(e),e!==this&&e.neighbors.add(this)}removeLink(e){this.neighbors.delete(e),e.neighbors.delete(this)}deleteLinks(){for(var e of this.neighbors)e.neighbors.delete(this);this.neighbors.clear()}}class Graph{constructor(){this.nodes=new Map}addNode(e,t){let i=this.getNode(e);return i?i.data=t:i=new Node(e,t),this.nodes.set(e,i),i}removeNode(e){let t=this.getNode(e);return!!t&&(t.deleteLinks(),this.nodes.delete(e),!0)}hasNode(e){return this.nodes.has(e)}getNode(e){return this.nodes.get(e)}getNodeCount(){return this.nodes.size}forEachNode(e){for(var t of this.nodes.values())e(t)}clear(){for(var e of this.nodes.values())e.deleteLinks();this.nodes.clear()}}class NodeHeap{constructor(e=[]){if(this.data=e,this.length=e.length,0<this.length)for(let e=this.length>>1;0<=e;e--)this.down(e);for(let e=0;e<this.length;++e)this.setNodeId(this.data[e],e)}compare(e,t){return e.fScore-t.fScore}setNodeId(e,t){e.heapIndex=t}push(e){this.data.push(e),this.setNodeId(e,this.length),this.length++,this.up(this.length-1)}pop(){if(0!==this.length){var e=this.data[0];return this.length--,0<this.length&&(this.data[0]=this.data[this.length],this.setNodeId(this.data[0],0),this.down(0)),this.data.pop(),e}}peek(){return this.data[0]}updateItem(e){this.down(e),this.up(e)}up(e){let t=this.data;for(var i=t[e];0<e;){var r=e-1>>1,s=t[r];if(0<=this.compare(i,s))break;t[e]=s,this.setNodeId(s,e),e=r}t[e]=i,this.setNodeId(i,e)}down(i){let r=this.data;for(var e=this.length>>1,s=r[i];i<e;){let e=1+(i<<1);var a=e+1;let t=r[e];if(a<this.length&&this.compare(r[a],t)<0&&(e=a,t=r[a]),0<=this.compare(t,s))break;r[i]=t,this.setNodeId(t,i),i=e}r[i]=s,this.setNodeId(s,i)}}class NodeSearchState{constructor(e){this.node=e,this.closed=!1,this.open=0,this.distanceToSource=Number.POSITIVE_INFINITY,this.fScore=Number.POSITIVE_INFINITY,this.heapIndex=-1}}function makeSearchStatePool(){let i=0,r=[];return{createNewState(e){let t=r[i];return t?(t.node=e,t.parent=void 0,t.closed=!1,t.open=0,t.distanceToSource=Number.POSITIVE_INFINITY,t.fScore=Number.POSITIVE_INFINITY,t.heapIndex=-1):(t=new NodeSearchState(e),r[i]=t),i++,t},reset(){i=0}}}function blindHeuristic(){return 0}function constantDistance(){return 1}function PathFinder(u,e={}){let d=e.bestEffort,p=e.maxExpandedNodes||Number.POSITIVE_INFINITY,g=e.heuristic??blindHeuristic,m=e.distance??constantDistance,y=e.excludedNodes,T=makeSearchStatePool();return{find:function(e,t){let i=u.getNode(e);if(!i)throw new Error("fromId is not defined in this graph: "+e);let r=u.getNode(t);if(!r)throw new Error("toId is not defined in this graph: "+t);if(i===r)return[];T.reset();let s=new Map,a=new NodeHeap,n=T.createNewState(i);if(s.set(e,n),n.fScore=y?.(r.data)?Number.POSITIVE_INFINITY:g(i,r),!Number.isFinite(n.fScore)&&i.neighbors.has(r))return[];n.distanceToSource=0,a.push(n),n.open=1;let o,l=n,h=0;for(;0<a.length;){if(o=a.pop(),o.node===r)return reconstructPath(o);if(h++,h>p)break;o.closed=!0,o.node.neighbors.forEach(c)}return d?reconstructPath(l):[];function c(e){let t=s.get(e.id);t||(t=T.createNewState(e),s.set(e.id,t)),t.closed||(0===t.open&&(a.push(t),t.open=1),(e=y?.(e.data)?Number.POSITIVE_INFINITY:o.distanceToSource+m(o.node,e))>=t.distanceToSource||(t.parent=o,t.distanceToSource=e,y?.(r.data)?t.fScore=Number.POSITIVE_INFINITY:t.fScore=e+g(t.node,r,t),t.fScore-t.distanceToSource<l.fScore-l.distanceToSource&&(l=t),a.updateItem(t.heapIndex)))}}}}function reconstructPath(e){let t=[e.node],i=e.parent;for(;i;)t.push(i.node),i=i.parent;return t}function distance(e,t){var i=Math.abs(e.data.tile.rx-t.data.tile.rx),t=Math.abs(e.data.tile.ry-t.data.tile.ry);return i+t+(Math.SQRT2-2)*Math.min(i,t)}function heuristic(e,t,i){var r=Math.abs(e.data.tile.rx-t.data.tile.rx),t=Math.abs(e.data.tile.ry-t.data.tile.ry);let s=r+t+(Math.SQRT2-2)*Math.min(r,t);return i?.parent&&(t=(r=i.parent.node).data.tile.rx-e.data.tile.rx,e=r.data.tile.ry-e.data.tile.ry,i.dirX=t,i.dirY=e,t===i.parent.dirX&&e===i.parent.dirY||(s+=.2)),s}class map_Terrain_Terrain{constructor(e,t,i,r,s){this.tiles=e,this.theaterType=t,this.mapBounds=i,this.tileOccupation=r,this.rules=s,this.passabilityGraphs=new Map,this.invalidatedTiles=new Map,this.tiberiumMayChangePassability=new Set,this.handleTileOccupationUpdate=({tiles:e,object:r})=>{e=e.filter(e=>{if(r.isOverlay()){if(r.isBridge())return!0;if(r.isTiberium()){var t=getLandType(e.terrainType);if(this.tiberiumMayChangePassability.has(t))return!0}}var i=SpeedType.Foot,t=!r.isTerrain();return this.isBlockerObject(r,e,!1,i,t)||r.isBuilding()&&r.rules.leaveRubble});e.length&&this.invalidateTiles(e)},this.handleMapBoundsResize=()=>{this.passabilityGraphs.clear()},r.onChange.subscribe(this.handleTileOccupationUpdate),i.onLocalResize.subscribe(this.handleMapBoundsResize),this.tiberiumMayChangePassability.clear();let a=this.rules.getLandRules(LandType.Tiberium);for(var n of Object.values(SpeedType).filter(e=>"string"!=typeof e)){var o,l=Boolean(Math.sign(a.getSpeedModifier(n)));for(o of Object.values(LandType).filter(e=>"string"!=typeof e))Boolean(Math.sign(this.rules.getLandRules(o).getSpeedModifier(n)))!==l&&this.tiberiumMayChangePassability.add(o)}}getGraphKey(e,t){return e+"_"+Number(t)}invalidateTiles(i){i.length&&[...this.passabilityGraphs.keys()].forEach(e=>{let t=this.invalidatedTiles.get(e);t?i.forEach(e=>t.add(e)):this.invalidatedTiles.set(e,new Set(i))})}computePath(s,a,e,t,i,r,{maxExpandedNodes:n=Number.POSITIVE_INFINITY,bestEffort:o=!0,excludeTiles:l,ignoredBlockers:h=[]}={}){let c=this.computePassabilityGraph(s,a);var u=h.map(e=>this.tileOccupation.calculateTilesForGameObject(e.tile,e)).reduce((e,t)=>e.concat(t),[]);u.length&&this.updatePassability(u,s,a,c,h);var d=this.getNodeId(e,t),p=!!c.hasNode(d);p||this.updatePassability([e],s,a,c,h,1);var g=this.getNodeId(i,r),m=!!c.hasNode(g);let y;var T=p&&!u.length;if(T){let i=this.getIslandIdMap(s,a),r=i.get(e,t);y=(e,t)=>i.get(e,t)===r}else y=(e,t)=>0<this.getPassableSpeed(e,s,a,t,h);if(!m||!y(i,r)){var f=T?15:5,f=o?new RadialTileFinder(this.tiles,this.mapBounds,i,{width:1,height:1},1,f,e=>y(e,!1)&&Math.abs(e.z-i.z)<2&&!l?.({tile:e,onBridge:void 0})).getNextTile():void 0;if(f)i=f,r=!1;else{if(T)return u.length&&this.updatePassability(u,s,a,c),[];c.addNode(g,{tile:i,onBridge:void 0}),n=Math.min(n,500)}}let v=PathFinder(c,{bestEffort:o,maxExpandedNodes:n,excludedNodes:l,distance:distance,heuristic:heuristic}),b=v.find(this.getNodeId(e,t),this.getNodeId(i,r)).map(e=>({tile:e.data.tile,onBridge:e.data.onBridge}));return(b.length<2||l&&b.length&&(!o&&b[0].tile!==i||b[b.length-1].tile!==e))&&(b=[]),p||(c.removeNode(d),this.updatePassability([e],s,a,c)),m||c.removeNode(g),u.length&&this.updatePassability(u,s,a,c),b}computeAllPassabilityGraphs(){Object.keys(SpeedType).forEach(e=>{e=Number(e);isNaN(e)||e===SpeedType.Winged||(this.computePassabilityGraph(e,!1),this.computePassabilityGraph(e,!0))})}computePassabilityGraph(t,i){var r=this.getGraphKey(t,i);let s=this.passabilityGraphs.get(r);if(s){let e=this.invalidatedTiles.get(r);e?.size&&(this.updatePassability([...e],t,i,s),e.clear(),this.computeIslandIds(s))}else s=new Graph,this.passabilityGraphs.set(r,s),this.tiles.forEach(e=>{this.computePassability(e,t,i,s)}),this.computeIslandIds(s);return s}updatePassability(t,i,r,s,a=[],n){let o=new Set;t.forEach(e=>{[e,this.tiles.getNeighbourTile(e,TileDirection.Right),this.tiles.getNeighbourTile(e,TileDirection.BottomRight),this.tiles.getNeighbourTile(e,TileDirection.Bottom),this.tiles.getNeighbourTile(e,TileDirection.BottomLeft)].filter(isNotNullOrUndefined).forEach(e=>o.add(e))});let l=new Map;t.forEach(e=>{var t;for(t of[s.getNode(this.getNodeId(e,!1)),s.getNode(this.getNodeId(e,!0))])t&&(l.set(t.id,t.data.islandId),s.removeNode(t.id))}),o.forEach(e=>{this.computePassability(e,i,r,s,a,n&&t.includes(e)?n:void 0)}),l.forEach((e,t)=>{let i=s.getNode(t);i&&(i.data.islandId=e)})}computePassability(e,t,i,r,s=[],a){var n=[TileDirection.Left,TileDirection.TopLeft,TileDirection.Top,TileDirection.TopRight];if(a||this.getPassableSpeed(e,t,i,!1,s)){var o,l=this.getNodeId(e,!1);r.hasNode(l)||r.addNode(l,{tile:e,onBridge:void 0,forceLandSpeed:a});for(o of n)this.connectTiles(e,void 0,o,t,i,r,s)}var h=this.tileOccupation.getBridgeOnTile(e);if(h&&(a||this.getPassableSpeed(e,t,i,!0,s))){var c,l=this.getNodeId(e,!0);r.hasNode(l)||r.addNode(l,{tile:e,onBridge:h,forceLandSpeed:a});for(c of n)this.connectTiles(e,h,c,t,i,r,s)}}connectTiles(i,r,s,a,n,o,l=[]){var h=this.tiles.getNeighbourTile(i,s);if(h){let e=this.tileOccupation.getBridgeOnTile(h);s=r||e?0:1;if(Math.abs(i.z+(r?.tileElevation??0)-(h.z+(e?.tileElevation??0)))>s){if(!e?.isHighBridge()&&!r?.isHighBridge()||0!==Math.abs(i.z-h.z)||!o.hasNode(this.getNodeId(i,!1)))return;r=e=void 0}s=this.getNodeId(h,!!e);let t=o.getNode(s);this.getPassableSpeed(h,a,n,!!e,l,void 0,t?.data.forceLandSpeed)&&(t=t??o.addNode(s,{tile:h,onBridge:e}),r=this.getNodeId(i,!!r),o.getNode(r).addLink(t))}}getNodeId(e,t){return e.id+(t?"_bridge":"")}computeIslandIds(e){let t=1;e.forEachNode(e=>{e.data.islandId=void 0}),e.forEachNode(e=>{e.data.islandId||this.floodIslandId(e,t++)})}floodIslandId(e,t){let i=[e];for(;i.length;){let e=i.pop();e.data.islandId=t;for(var r of e.neighbors)r.data.islandId||i.push(r)}}getIslandIdMap(e,t){let i=this.computePassabilityGraph(e,t);return{get:(e,t)=>{t=this.getNodeId(e,t);return i.getNode(t)?.data.islandId}}}getPassableSpeed(e,t,i,r,s=[],a=!1,n){if(!this.mapBounds.isWithinBounds(e))return 0;let o=r?e.onBridgeLandType:e.landType;if(void 0===o)return 0;o===LandType.Wall&&t===SpeedType.Track&&(o=getLandType(e.terrainType));let l=this.rules.getLandRules(o);var h,n=n||l.getSpeedModifier(t);if(!n)return 0;if(!a)for(h of this.tileOccupation.getObjectsOnTile(e))if(this.isBlockerObject(h,e,r,t,i)&&!s.includes(h))return 0;return n}isBlockerObject(t,i,e,r,s){if(t.rules.crushable&&[SpeedType.Track,SpeedType.Hover].includes(r))return!1;if(t.isTerrain())return!s||t.rules.getOccupationBits(this.theaterType)===OccupationBits.All;if(t.isBuilding()){if(t.rules.invisibleInGame)return!1;if(t.isDestroyed&&t.rules.leaveRubble)return!1;if(t.rules.gate)return!1;r=t.art.foundation;let e=t.rules.numberImpassableRows;return s?e=r.width:t.rules.weaponsFactory&&!e&&(e=r.width-1),rectContainsPoint({x:t.tile.rx,y:t.tile.ry,width:(e||r.width)-1,height:r.height-1},{x:i.rx,y:i.ry})}return!(t.isAircraft()||t.isInfantry()||t.isVehicle()||t.isSmudge()||t.isOverlay()&&(e&&t.isBridge()||!e&&t.isHighBridge()||t.isTiberium()||t.rules.crate||t.isBridgePlaceholder()))}findObstacles(t,e){var i,r,s=e.rules.speedType,a=e.isInfantry();let n=[];for(i of this.tileOccupation.getGroundObjectsOnTile(t.tile))i!==e&&(((r=this.isBlockerObject(i,t.tile,!!t.onBridge,s,a))||i.isUnit()&&(i.tile===t.tile&&i.onBridge===!!t.onBridge||i.moveTrait.reservedPathNodes.find(e=>e.tile===t.tile&&!!e.onBridge==!!t.onBridge))||[SpeedType.Track,SpeedType.Hover].includes(s)&&i.rules.crushable||a&&i.isTerrain()||i.isBuilding()&&i.rules.gate)&&(r={obj:i,static:r},i.isInfantry()&&a?i.position.desiredSubCell===e.position.desiredSubCell&&n.push(r):i.isTerrain()&&a&&!i.rules.getOccupiedSubCells(this.theaterType).includes(e.position.desiredSubCell)||n.push(r)));return n}dispose(){this.tileOccupation.onChange.unsubscribe(this.handleTileOccupationUpdate),this.mapBounds.onLocalResize.unsubscribe(this.handleMapBoundsResize)}}class MapBounds{constructor(){this.mapCutoffHeight=0,this.mapBuildableSize={x:0,y:0,width:0,height:0},this.localSize={x:0,y:0,width:0,height:0},this.fullSize={width:0,height:0},this.clampedFullSize={x:0,y:0,width:0,height:0},this.rawLocalSize={x:0,y:0,width:0,height:0},this._onLocalResize=new EventDispatcher}get onLocalResize(){return this._onLocalResize.asEvent()}fromMapFile(e,t){this.fullSize={width:2*e.fullSize.width,height:2*e.fullSize.height},this.clampedFullSize={x:1,y:2,width:2*(e.fullSize.width-1)-1/Coords.ISO_TILE_SIZE,height:2*(e.fullSize.height-1)+1-1/Coords.ISO_TILE_SIZE},this.mapCutoffHeight=Math.max(9,t.getCutoffTileHeight());t=Math.max(2,e.localSize.x),e={x:t,y:e.localSize.y,width:Math.min(e.fullSize.width-2-t,e.localSize.width),height:e.localSize.height};return this.updateRawLocalSize(e),this}updateRawLocalSize(e){this.rawLocalSize.width&&this.rawLocalSize.height&&!rectContainsRect(e,this.rawLocalSize)?console.warn("New map limits must be outside old limits. Skipping."):rectEquals(e,this.rawLocalSize)||(this.localSize=this.computeLocalSize(e,this.fullSize.height/2,this.mapCutoffHeight),this.rawLocalSize={...e},this.mapBuildableSize={x:this.localSize.x,y:this.localSize.y+4,width:this.localSize.width-2,height:this.localSize.height-8},this._onLocalResize.dispatch(this))}computeLocalSize(e,t,i){return{x:2*e.x,y:2*e.y-4,height:Math.min(2*(e.height+5)-1,2*t-2*(e.y-3)-i),width:2*e.width}}getLocalSize(){return this.localSize}getRawLocalSize(){return this.rawLocalSize}getFullSize(){return this.fullSize}getClampedFullSize(){return this.clampedFullSize}isWithinBounds(e){return rectContainsPoint(this.mapBuildableSize,{x:e.dx,y:e.dy-e.z})}clampWithinBounds(e){let{x:t,y:i}=rectClampPoint(this.mapBuildableSize,{x:e.dx,y:e.dy-e.z});return i+=t%2-i%2,i>this.mapBuildableSize.y+this.mapBuildableSize.height&&(i-=2),{dx:t,dy:i}}isWithinHardBounds(e){var t=e.x/Coords.LEPTONS_PER_TILE,i=(e.z??e.y)/Coords.LEPTONS_PER_TILE,e=t-i+this.fullSize.width/2-1,i=t+i-this.fullSize.width/2-1;return rectContainsPoint(this.clampedFullSize,{x:++e,y:++i})}}class DirectionalTileFinder{constructor(e,t,i,r,s,a,n,o=()=>!0,l=!0){this.tiles=e,this.mapBounds=t,this.startTile=i,this.maxDistance=s,this.dirX=a,this.dirY=n,this.predicate=o,this.checkBounds=l,this.finished=!1,this.distance=r}getNextTile(){if(!this.finished){let t;do{let e={x:this.startTile.rx,y:this.startTile.ry};e.x+=this.distance*Math.sign(this.dirX),e.y+=this.distance*Math.sign(this.dirY);var i=this.tiles.getByMapCoords(e.x,e.y);if(i&&(!this.checkBounds||this.mapBounds.isWithinBounds(i))&&this.predicate(i)&&(t=i),this.maxDistance&&this.distance>=this.maxDistance)return this.finished=!0,t}while(this.distance++,!t);return t}}}!function(e){e[e.None=0]="None",e[e.Start=1]="Start",e[e.End=2]="End"}(BridgeHeadType=BridgeHeadType||{});class Bridges{constructor(e,t,i,r,s){this.tileSets=e,this.tiles=t,this.tileOccupation=i,this.mapBounds=r,this.rules=s,this.pieces=new Set,this.piecesByTile=new Map,this.handleTileOccupationUpdate=({object:t,type:i})=>{if(t.isOverlay()&&t.isBridge()){var r=t.tile;let e=this.piecesByTile.get(r);if("added"===i){if(e)throw new Error(`A bridge piece already exists at tile (${r.rx},${r.ry})`);var s=this.findBridgeAdjacentTiles(t);e={obj:t,prev:void 0,next:void 0,headType:this.computeHead(t,s.prev,s.next)},this.piecesByTile.set(r,e),this.pieces.add(e),this.connectPiece(e,s.prev,s.next),this.updateOverlayData(e),e.prev&&this.updateOverlayData(e.prev),e.next&&this.updateOverlayData(e.next)}else{if(!e)throw new Error(`Bridge piece was alredy removed at tile (${r.rx},${r.ry})`);t=e.prev,s=e.next;this.disconnectPiece(e),this.piecesByTile.delete(r),this.pieces.delete(e),t&&this.updateOverlayData(t),s&&this.updateOverlayData(s)}}},i.onChange.subscribe(this.handleTileOccupationUpdate)}getPieceAtTile(e){return this.piecesByTile.get(e)}handlePieceHealthChange(e){this.updateOverlayData(e),e.prev&&this.updateOverlayData(e.prev),e.next&&this.updateOverlayData(e.next)}findDominoPieces(t){let i=[],r=!1,e=t.next;if(t.headType===BridgeHeadType.None||e)for(;e;){if(i.push(e),e.headType!==BridgeHeadType.None){r=!0;break}e=e.next}else r=!0;if(r){r=!1,i.length=0;let e=t.prev;if(t.headType===BridgeHeadType.None||e)for(;e;){if(i.push(e),e.headType!==BridgeHeadType.None){r=!0;break}e=e.prev}else r=!0;if(r)return[]}return i}findBridgeAdjacentTiles(e){var t=e.isXBridge(),t=new Vector2(Number(t),Number(!t));let i=new Vector2(e.tile.rx,e.tile.ry);e=i.clone().sub(t),e=this.tiles.getByMapCoords(e.x,e.y),t=i.clone().add(t);return{prev:e,next:this.tiles.getByMapCoords(t.x,t.y)}}connectPiece(e,t,i){t&&(e.prev=this.getPieceAtTile(t),e.prev&&(e.prev.next=e)),i&&(e.next=this.getPieceAtTile(i),e.next&&(e.next.prev=e))}disconnectPiece(e){e.next&&(e.next.prev=void 0,e.next=void 0),e.prev&&(e.prev.next=void 0,e.prev=void 0)}computeHead(e,t,i){var r=e.tile;if(e.isHighBridge()){r=r.z+e.tileElevation;return t?.z===r?BridgeHeadType.Start:i?.z===r?BridgeHeadType.End:BridgeHeadType.None}return BridgeOverlayTypes.isLowBridgeHead(e.overlayId)?BridgeOverlayTypes.isLowBridgeHeadStart(e.overlayId)?BridgeHeadType.Start:BridgeHeadType.End:BridgeHeadType.None}updateOverlayData(t){let i=t.obj,r=t.prev,s=t.next,a=!1;var n=i.isXBridge(),o=BridgeOverlayTypes.getOverlayBridgeType(i.overlayId);if(BridgeOverlayTypes.isLowBridgeHead(i.overlayId)){let e=0;BridgeOverlayTypes.isLowBridgeHeadStart(i.overlayId)?(e=n?20:22,s||e++):(e=n?18:24,r||e++),i.overlayId=(o===OverlayBridgeType.Wood?BridgeOverlayTypes.minLowBridgeWoodId:BridgeOverlayTypes.minLowBridgeConcreteId)+e,i.value=e,a=!0}else{let e;var l,h=(i.healthTrait?.health??100)<=50;e=t.headType!==BridgeHeadType.None?t.headType===BridgeHeadType.Start?s?h?6:(s.obj.healthTrait?.health??100)<=50?5:0:n?8:7:r?h?6:(r.obj.healthTrait?.health??100)<=50?4:0:n?7:8:(n||(l=r,r=s,s=l),r||s?r?s?(t=(r.obj.healthTrait?.health??100)<=50,l=(s.obj.healthTrait?.health??100)<=50,h||t&&l?6:t?4:l?5:0):8:7:0),n||(e+=9),i.isHighBridge()?i.value=e:(i.overlayId=(o===OverlayBridgeType.Wood?BridgeOverlayTypes.minLowBridgeWoodId:BridgeOverlayTypes.minLowBridgeConcreteId)+e,i.value=e,a=!0)}a&&(i.name=this.rules.getOverlayName(i.overlayId))}findClosestBridgeSpec(i){let e=new RadialTileFinder(this.tiles,this.mapBounds,i,{width:1,height:1},1,3,e=>{if(e.z!==i.z)return!1;let t=this.tileOccupation.getBridgeOnTile(e);return!(!t?.isLowBridge()||this.getPieceAtTile(t.tile)?.headType===BridgeHeadType.None)||!!this.tileSets.isHighBridgeBoundaryTile(e.tileNum)},!1);var o=e.getNextTile();if(o){let r,t,s,a;var l=!this.tileOccupation.getBridgeOnTile(o);let e;if(l){var h=this.findHighBridgeBoundary(o);if(!h)return;r=h.tile,t=OverlayBridgeType.Concrete,this.tileSets.getSetNum(o.tileNum)===this.tileSets.getGeneralValue("WoodBridgeSet")&&(t=OverlayBridgeType.Wood),s=h.headType===HighBridgeHeadType.TopLeft||h.headType===HighBridgeHeadType.BottomRight,a=h.headType===HighBridgeHeadType.TopLeft||h.headType===HighBridgeHeadType.TopRight,e=h.headType}else{r=this.tileOccupation.getBridgeOnTile(o).tile;let e=this.getPieceAtTile(r);if(!e)throw new Error("Bridge head is not defined");var c=BridgeOverlayTypes.getOverlayBridgeType(e.obj.overlayId);if(c===OverlayBridgeType.NotBridge)throw new Error("Expected a bridge type");t=c,s=e.obj.isXBridge(),a=e.headType===BridgeHeadType.Start}var u=Number(s)*(a?1:-1),d=Number(!s)*(a?1:-1);let n;if(l){o=new DirectionalTileFinder(this.tiles,this.mapBounds,r,1,100,u,d,e=>e.z===r.z&&this.tileSets.isHighBridgeBoundaryTile(e.tileNum),!1).getNextTile(),c=this.tileSets.getSetNum(r.tileNum);if(!o||this.tileSets.getSetNum(o.tileNum)!==c)return;o=this.findHighBridgeBoundary(o);if(!o)return;if(e!==this.tileSets.getOppositeHighBridgeHeadType(o.headType))return;n=o.tile}else{let t,i=1;for(var p=r.rx,g=r.ry;!t;){var m=this.tiles.getByMapCoords(p+u*i,g+d*i);if(!m)return;let e=this.getPieceAtTile(m);if(e&&e.obj.isXBridge()!==s)return;e?.headType===(a?BridgeHeadType.End:BridgeHeadType.Start)&&(t=e),i++}n=t.obj.tile}return{start:a?r:n,end:a?n:r,type:t,isHigh:l,isXBridge:s}}}findHighBridgeBoundary(e){let t=this.tileSets.getTile(e.tileNum);var s=this.tileSets.getHighBridgeHeadType(t.index);if(void 0!==s){let i=0,r=0;switch(s){case HighBridgeHeadType.TopLeft:i=1,r=0;break;case HighBridgeHeadType.BottomRight:i=-1,r=0;break;case HighBridgeHeadType.TopRight:i=0,r=1;break;case HighBridgeHeadType.BottomLeft:i=0,r=-1;break;case HighBridgeHeadType.MiddleTlBr:i=1,r=0;break;case HighBridgeHeadType.MiddleTrBl:i=0,r=1;break;default:throw new Error(`Unhandled head type "${s}"`)}const h=t.getRelativeTilePositions();var a=h.filter(e=>4===e.z).sort((e,t)=>100*(i?i*(t.rx-e.rx):r*(t.ry-e.ry))+(i?e.ry-t.ry:e.rx-t.rx))[0].subTile,n=h[a].rx-h[e.subTile].rx,o=h[a].ry-h[e.subTile].ry,l=this.tiles.getByMapCoords(e.rx+n,e.ry+o);if(l){if(l.subTile===a&&l.tileNum===e.tileNum)return{tile:l,headType:s};console.warn("Found invalid bridge boundary tile. "+`(${e.rx},${e.ry})+(${n},${o})`)}}else console.warn(`Couldn't find a valid bridge type for index "${t.index}" @ ${e.rx},`+e.ry)}canBeRepaired(i){let e=this.createBridgePieceTileFinder(i,e=>!(this.getPieceAtTile(e)||this.tileSets.isHighBridgeMiddleTile(e.tileNum)&&e.z===i.start.z)),r=!1,s;for(var a=i.start.rx!==i.end.rx?TileDirection.BottomLeft:TileDirection.BottomRight;s=e.getNextTile();){r=!0;let e=this.tiles.getNeighbourTile(s,a),t=this.tiles.getNeighbourTile(e,a);if(i.isHigh){if([s,e,t].find(e=>this.tileOccupation.getGroundObjectsOnTile(e).some(e=>e.isBuilding()&&!e.rules.invisibleInGame)))return!1}else if([s,e,t].find(e=>this.tileOccupation.getGroundObjectsOnTile(e).some(e=>!(e.isUnit()||e.isSmudge()||e.isOverlay()&&e.isBridgePlaceholder()))))return!1}return r}getPieceTiles(e){var t=e.obj.tile,i=e.obj.isXBridge()?TileDirection.BottomLeft:TileDirection.BottomRight,e=this.tiles.getNeighbourTile(t,i);return[t,e,this.tiles.getNeighbourTile(e,i)]}findMapHighBridgeHeadTiles(){var e,t=this.tiles.getAllBridgeSetTiles();let i=new Set;for(e of t){var r=this.findHighBridgeBoundary(e);r&&i.add(r.tile)}return i}findBridgeSpecsForHeadTiles(e){let t=new Map;for(var i of e){i=this.findClosestBridgeSpec(i);i&&t.set(i.start.id+":"+i.end.id,i)}return[...t.values()]}findAllBridgeTiles(e){let t=[];var i,r=e.start.rx!==e.end.rx?TileDirection.BottomLeft:TileDirection.BottomRight;for(i of this.findNonBuildablePieceTiles(e)){var s=this.tiles.getNeighbourTile(i,r),a=this.tiles.getNeighbourTile(s,r);t.push(i,s,a)}return t}getBridgeSize(e){var t=e.start.rx!==e.end.rx;return{width:t?e.end.rx-e.start.rx+1:3,height:t?3:e.end.ry-e.start.ry+1}}findBridgePieces(e){let t=this.createBridgePieceTileFinder(e,e=>!!this.getPieceAtTile(e)),i=[];for(var r;r=t.getNextTile();)i.push(this.getPieceAtTile(r));return i}findDestroyedPieceTiles(t){let e=this.createBridgePieceTileFinder(t,e=>!(this.getPieceAtTile(e)||this.tileSets.isHighBridgeMiddleTile(e.tileNum)&&e.z===t.start.z)),i=[];for(var r;r=e.getNextTile();)i.push(r);return i}findNonBuildablePieceTiles(t){let e=this.createBridgePieceTileFinder(t,e=>!(this.tileSets.isHighBridgeMiddleTile(e.tileNum)&&e.z===t.start.z)),i=[];for(var r;r=e.getNextTile();)i.push(r);return i}createBridgePieceTileFinder(e,t){var i=e.start.rx!==e.end.rx;return new DirectionalTileFinder(this.tiles,this.mapBounds,e.start,1,(i?e.end.rx-e.start.rx:e.end.ry-e.start.ry)-1,Number(i),Number(!i),t,!1)}dispose(){this.pieces.forEach(e=>{e.prev=void 0,e.next=void 0}),this.tileOccupation.onChange.unsubscribe(this.handleTileOccupationUpdate)}}var AllianceStatus,SelectionLevel,NotifySpawn_NotifySpawn,NotifyUnspawn_NotifyUnspawn,NotifyOwnerChange_NotifyOwnerChange,NotifyAllianceChange,NotifyDestroy_NotifyDestroy,AllianceEventType,QuadTree_THREE=__webpack_require__(70);const tmpVec2=new QuadTree_THREE.Vector2;class QuadTree{constructor(e,t){this.box=e,this.config=t,this.parentMap=new Map,this.objects=[]}add(e,t=!0){var i=this.config.getKey(e);if(this.box.containsPoint(i)){if(!this.regions)return this.parentMap.get(e)?.remove(e),this.parentMap.set(e,this),this.objects.push({key:i,value:e}),t&&this.update(),!0;for(var r of this.regions)if(r.add(e,t))return!0}return!1}remove(t,e=!0){let i=this.parentMap.get(t);i&&(i===this?(this.parentMap.delete(t),this.objects.splice(this.objects.findIndex(e=>e.value===t),1),e&&this.parent?.update()):i.remove(t,e))}updateObject(t){let i=this.parentMap.get(t);if(i){var e=this.config.getKey(t);if(i.box.containsPoint(e))i.objects.find(e=>e.value===t).key=e;else{i.remove(t,!1);let e=i.parent;for(;e&&!e.add(t,!1);)e=e.parent}}}queryRange(e,t=[]){if(this.box.intersectsBox(e))if(this.regions)for(var i of this.regions)i.queryRange(e,t);else for(var r of this.objects)e.containsPoint(r.key)&&t.push(r.value);return t}update(){let e=0;if(this.regions){for(var t of this.regions)e+=t.update();e<=this.config.joinThreshold&&this.join()}else e=this.objects.length,e>=this.config.splitThreshold&&this.split()&&this.update();return e}split(){if(this.regions||this.config.maxDepth<=1)return!1;var t,e,i={getKey:this.config.getKey,joinThreshold:this.config.joinThreshold,splitThreshold:this.config.splitThreshold,maxDepth:this.config.maxDepth-1},r=this.generateRegions(),s=this.objects;this.objects=[],this.regions=[];for(t of r){let e=new QuadTree(t,i);e.parentMap=this.parentMap,this.regions.push(e),e.parent=this}for(e of s)this.parentMap.delete(e.value),this.add(e.value,!1);return!0}join(){if(!this.regions)return!1;for(var e of this.regions){e.join(),e.parent=void 0;for(var t of e.objects)this.objects.push(t),this.parentMap.set(t.value,this)}return!(this.regions=void 0)}generateRegions(){let i=[this.box.clone()];var r=this.box.getCenter(tmpVec2);let s=i[0],a=s.clone();s.max.x=r.x,a.min.x=r.x,i.push(a);for(let e=0,t=i.length;e<t;e++)s=i[e],a=s.clone(),s.max.y=r.y,a.min.y=r.y,i.push(a);return i}}class TileOcclusion{constructor(e){this.tiles=e,this.tileOcclusion=[];let t=this.tileOcclusion;for(var i of e.getAll())t[i.rx]=t[i.rx]||[],t[i.rx][i.ry]=new Set}addOccluder(t){let e=this.calculateTilesForGameObject(t);e.forEach(e=>this.occludeTile(e,t))}removeOccluder(t){let e=this.calculateTilesForGameObject(t);e.forEach(e=>this.unoccludeTile(e,t))}calculateTilesForGameObject(e){var t=e.art.occupyHeight,i=Math.max(0,t-2);let r=[];var s=e.getFoundation();for(let t=1;t<=i;t++)for(let e=0;e<s.width;e++)r.push(new Vector2(e-t,-t));for(let t=1;t<=i;t++)for(let e=1;e<s.height;e++)r.push(new Vector2(-t,e-t));r.push(...e.art.addOccupy);for(let{x:t,y:i}of e.art.removeOccupy){var a=r.findIndex(e=>e.x===t&&e.y===i);-1!==a&&r.splice(a,1)}var n,o,l=e.tile;let h=[];for({x:n,y:o}of r){var c=this.tiles.getByMapCoords(l.rx+n,l.ry+o);c&&h.push(c)}return h}occludeTile(e,t){this.tileOcclusion[e.rx][e.ry].add(t),e.occluded=!0}unoccludeTile(e,t){let i=this.tileOcclusion[e.rx][e.ry];i.delete(t),e.occluded=0<i.size}isTileOccluded(e){return 0<this.tileOcclusion[e.rx][e.ry].size}}class AutoLat{static calculate(u,d){let p=new Map;u.forEach(e=>{var t=d.getSetNum(e.tileNum);p.set(e,t),d.isCLAT(t)&&(t=d.getLAT(t),p.set(e,t),e.tileNum=d.getTileNumFromSet(t))}),u.forEach(t=>{var i=p.get(t);if(d.isLAT(i)){let e=0;var r=u.getNeighbourTile(t,TileDirection.TopRight),s=u.getNeighbourTile(t,TileDirection.BottomRight),a=u.getNeighbourTile(t,TileDirection.BottomLeft),n=u.getNeighbourTile(t,TileDirection.TopLeft);r&&d.canConnectTiles(i,p.get(r))&&(e+=1),s&&d.canConnectTiles(i,p.get(s))&&(e+=2),a&&d.canConnectTiles(i,p.get(a))&&(e+=4),n&&d.canConnectTiles(i,p.get(n))&&(e+=8),0<e&&(n=d.getCLATSet(i),t.tileNum=d.getTileNumFromSet(n,e))}else if(i===d.getGeneralValue("RampBase")&&!(t.rampType<1||4<t.terrainType)){let e=-1;var o=u.getNeighbourTile(t,TileDirection.TopRight),l=u.getNeighbourTile(t,TileDirection.BottomRight),h=u.getNeighbourTile(t,TileDirection.BottomLeft),c=u.getNeighbourTile(t,TileDirection.TopLeft);switch(t.rampType){case 1:c&&0===c.rampType&&e++,l&&0===l.rampType&&(e+=2);break;case 2:o&&0===o.rampType&&e++,h&&0===h.rampType&&(e+=2);break;case 3:l&&0===l.rampType&&e++,c&&0===c.rampType&&(e+=2);break;case 4:h&&0===h.rampType&&e++,o&&0===o.rampType&&(e+=2)}-1!==e&&(t.tileNum=d.getTileNumFromSet(d.getGeneralValue("RampSmooth"),3*(t.rampType-1)+e))}})}}class GameMap{get startingLocations(){return this.mapFile.startingLocations}constructor(e,t,i,r){this.mapFile=e,this.tiles=new TileCollection(this.mapFile.tiles,t,i.general,r),this.mapBounds=(new MapBounds).fromMapFile(this.mapFile,this.tiles),this.tileOccupation=new TileOccupation(this.tiles),this.tileOcclusion=new TileOcclusion(this.tiles),this.terrain=new map_Terrain_Terrain(this.tiles,this.mapFile.theaterType,this.mapBounds,this.tileOccupation,i),this.bridges=new Bridges(t,this.tiles,this.tileOccupation,this.mapBounds,i);let s=this.mapFile.tags;for(let t of this.mapFile.cellTags){let e=this.tiles.getByMapCoords(t.coords.x,t.coords.y);e&&(e.tag=s.find(e=>e.id===t.tagId))}r=this.tiles.getMapSize(),i=Math.max(r.width,r.height)/5;this.technosByTile=new QuadTree(new Box2(new Vector2(0,0),new Vector2(r.width,r.height)),{getKey:e=>{e=e.isBuilding()?e.centerTile:e.tile;return new Vector2(e.rx,e.ry)},maxDepth:this.computeQuadDepth(i),splitThreshold:10,joinThreshold:5}),this.mapFile.theaterType!==TheaterType.Snow&&AutoLat.calculate(this.tiles,t)}computeQuadDepth(e){if(e<=1)return 1;let t=0;for(;1<=e/2;)e/=2,t++;return t+(1<e?1:0)}getLighting(){return this.mapFile.lighting}getIonLighting(){return this.mapFile.ionLighting}getTheaterType(){return this.mapFile.theaterType}getTags(){return this.mapFile.tags}getTriggers(){return this.mapFile.triggers}getCellTags(){return this.mapFile.cellTags}getVariables(){return this.mapFile.variables}getWaypoint(t){return this.mapFile.waypoints.find(e=>e.number===t)}getTileAtWaypoint(e){e=this.getWaypoint(e);if(e){e=this.tiles.getByMapCoords(e.rx,e.ry);if(e)return e}}isWithinBounds(e){return this.mapBounds.isWithinBounds(e)}clampWithinBounds(e){var t=this.mapBounds.clampWithinBounds(e);let i=this.tiles.getByDisplayCoords(t.dx,t.dy);if(i&&this.mapBounds.isWithinBounds(i)){let e=i,t=i.z;for(;0<=t&&e&&this.mapBounds.isWithinBounds(e);)i=e,e=this.tiles.getByDisplayCoords(e.dx,e.dy+2),t-=2}else{let e=0;for(;!i||!this.mapBounds.isWithinBounds(i);){if(30<e)throw new Error("Exceeded max elevation while trying to clamp tile to map bounds");i=this.tiles.getByDisplayCoords(t.dx,t.dy+e),e+=2}}return i}isWithinHardBounds(e){return this.mapBounds.isWithinHardBounds(e)}getInitialMapObjects(){return{terrains:this.mapFile.terrains,overlays:this.mapFile.overlays,smudges:this.mapFile.smudges,technos:[...this.mapFile.structures,...this.mapFile.infantries,...this.mapFile.vehicles,...this.mapFile.aircrafts]}}getObjectsOnTile(e){return this.tileOccupation.getObjectsOnTile(e)}getGroundObjectsOnTile(e){return this.tileOccupation.getGroundObjectsOnTile(e)}getTileZone(e,t=!1){return this.tileOccupation.getTileZone(e,t)}dispose(){this.terrain.dispose(),this.bridges.dispose()}}class PlayerPair{constructor(e,t){this.first=e,this.second=t}has(e){return this.first===e||this.second===e}equals(e){return this.first===e.first&&this.second===e.second||this.first===e.second&&this.second===e.first}}!function(e){e[e.Requested=0]="Requested",e[e.Formed=1]="Formed"}(AllianceStatus=AllianceStatus||{});class Alliances{constructor(e){this.playerList=e,this.alliances=[]}findByPlayers(e,t){let i=new PlayerPair(e,t);return this.alliances.find(e=>e.players.equals(i))}filterByPlayer(t){return this.alliances.filter(e=>e.players.first===t||e.players.second===t)}request(e,t){if(!this.canRequestAlliance(t))throw new Error(`Player ${t.name} is not a human combatant.`);if(this.canFormAlliance(e,t)){if(this.findByPlayers(e,t))throw new Error("Can't request alliance because an alliance is already pending or formed between "+`${e.name} and ${t.name}.`);return this.setAlliance(e,t,AllianceStatus.Requested)}}cancelRequest(e,t){var i=this.findByPlayers(e,t);if(!i||i.status!==AllianceStatus.Requested)throw new Error(`There is no pending alliance request for player ${t.name} from player `+e.name);if(i.players.first!==e)throw new Error(`Can't cancel request initiated by the other player (${t.name})`);this.alliances.splice(this.alliances.indexOf(i),1)}acceptRequest(t,i){if(this.canFormAlliance(t,i)){let e=this.findByPlayers(t,i);if(!e||e.status!==AllianceStatus.Requested)throw new Error(`There is no pending alliance request for player ${i.name} from player `+t.name);if(e.players.first!==t)throw new Error("Can't accept own alliance request for player "+i.name);e.status=AllianceStatus.Formed}}setAlliance(e,t,i){if(!this.canFormAlliance(e,t))throw new Error(`Can't form alliance between players "${e.name}" and "${t.name}"`);var r;if(r=this.findByPlayers(e,t))throw new Error(`An alliance already exists between players ${e.name} and `+t.name);return r={players:new PlayerPair(e,t),status:i},this.alliances.push(r),r}breakAlliance(e,t){var i=this.findByPlayers(e,t);if(!i||i.status!==AllianceStatus.Formed)throw new Error(`There is no alliance between player ${e.name} and player `+t.name);this.alliances.splice(this.alliances.indexOf(i),1)}areAllied(e,t){t=this.findByPlayers(e,t);return!!t&&t.status===AllianceStatus.Formed}getAllies(t){return this.filterByPlayer(t).filter(e=>e.status===AllianceStatus.Formed).map(e=>e.players.first===t?e.players.second:e.players.first)}haveSharedIntel(e,t){return e.isObserver||t.isObserver||e===t||this.areAllied(e,t)}canRequestAlliance(e){return e.isCombatant()&&!e.isAi}canFormAlliance(t,i){let e=this.getHostilePlayers();if(0===e.filter(e=>e.has(t)&&!e.has(i)).length)return!1;if(0===e.filter(e=>e.has(i)&&!e.has(t)).length)return!1;let r=new PlayerPair(t,i);return!!e.filter(e=>!e.equals(r)).length}getHostilePlayers(){var i,r=this.playerList.getCombatants();let s=[];for(let t=0;t<r.length;t++)for(let e=t+1;e<r.length;e++)this.getAllies(r[t]).includes(r[e])||(i=new PlayerPair(r[t],r[e]),s.push(i));return s}getHash(){return fnv32a(this.alliances.map(e=>[this.playerList.getPlayerNumber(e.players.first),this.playerList.getPlayerNumber(e.players.second),e.status]).flat())}debugGetState(){return this.alliances.map(e=>({first:e.players.first,second:e.players.second,status:e.status}))}}class PlayerList{constructor(){this.players=[]}addPlayer(e){this.players.push(e)}getPlayerAt(e){if(e>=this.players.length)throw new RangeError(`Player #${e} out of bounds`);return this.players[e]}getPlayerByName(t){var e=this.players.find(e=>e.name===t);if(!e)throw new Error(`Player with name "${t}" not found`);return e}getPlayerNumber(e){var t=this.players.indexOf(e);if(-1===t)throw new Error(`Player ${e.name} not found`);return t}getCombatants(){return this.players.filter(e=>e.isCombatant())}getNonNeutral(){return this.players.filter(e=>!e.isNeutral)}getCivilian(){return this.players.find(e=>e.country?.side===SideType.Civilian)}getAll(){return this.players}}!function(e){e[e.None=0]="None",e[e.Hover=1]="Hover",e[e.Selected=2]="Selected",e[e.SelectedHover=3]="SelectedHover"}(SelectionLevel=SelectionLevel||{});class SelectionModel{constructor(e){this.selectionLevel=SelectionLevel.None,e.isBuilding()&&e.rules.wall?this.maxSelectionLevel=SelectionLevel.None:this.maxSelectionLevel=e.rules.selectable?SelectionLevel.Selected|SelectionLevel.Hover:SelectionLevel.Hover}getSelectionLevel(){return this.selectionLevel}setSelectionLevel(e){this.selectionLevel=Math.min(this.maxSelectionLevel,e)}setHover(e){this.setSelectionLevel(e?this.selectionLevel|SelectionLevel.Hover:this.selectionLevel&~SelectionLevel.Hover)}setSelected(e){this.setSelectionLevel(e?this.selectionLevel|SelectionLevel.Selected:this.selectionLevel&~SelectionLevel.Selected)}isHovered(){return this.selectionLevel>>SelectionLevel.Hover&1}isSelected(){return this.selectionLevel>=SelectionLevel.Selected}getControlGroupNumber(){return this.controlGroupNumber}setControlGroupNumber(e){this.controlGroupNumber=e}}class UnitSelection{constructor(){this.selectedUnits=new Set,this.selectionModelsByUnit=new Map,this.groups=new Map,this.hashNeedsUpdate=!0}getOrCreateSelectionModel(e){let t=this.selectionModelsByUnit.get(e);return t||(t=new SelectionModel(e),this.selectionModelsByUnit.set(e,t)),t}deselectAll(){this.selectedUnits.forEach(e=>this.selectionModelsByUnit.get(e)?.setSelected(!1)),this.selectedUnits.clear(),this.hashNeedsUpdate=!0}addToSelection(e){this.selectedUnits.add(e),this.getOrCreateSelectionModel(e).setSelected(!0),this.hashNeedsUpdate=!0}removeFromSelection(e){e.forEach(e=>{this.selectedUnits.delete(e),this.getOrCreateSelectionModel(e).setSelected(!1)}),this.hashNeedsUpdate=!0}getSelectedUnits(){return[...this.selectedUnits].filter(e=>!e.isDestroyed&&!e.isCrashing&&!e.isDisposed&&e.isSpawned)}isSelected(e){return this.selectedUnits.has(e)}cleanupUnit(e){this.selectionModelsByUnit.delete(e),this.selectedUnits.delete(e),this.removeUnitsFromGroup([e]),this.hashNeedsUpdate=!0}updateHash(){this.hash=fnv32a([...this.selectedUnits].map(e=>e.id))}getHash(){return this.hashNeedsUpdate&&(this.updateHash(),this.hashNeedsUpdate=!1),this.hash}createGroup(e){this.addUnitsToGroup(e,this.getSelectedUnits())}addUnitsToGroup(e,t,i=!0){this.removeUnitsFromGroup(t);let r=this.groups.get(e);r||(r=new Set,this.groups.set(e,r)),i&&([...r.values()].forEach(e=>this.selectionModelsByUnit.get(e)?.setControlGroupNumber(void 0)),r.clear());for(var s of t)r.add(s),this.getOrCreateSelectionModel(s).setControlGroupNumber(e)}addGroupToSelection(e){if(this.groups.has(e))for(var t of[...this.groups.get(e)])this.addToSelection(t)}selectGroup(e){this.deselectAll(),this.addGroupToSelection(e)}getGroupUnits(e){return[...this.groups.get(e)??[]]}removeUnitsFromGroup(e){for(var t of this.groups.values())for(var i of e)t.delete(i),this.selectionModelsByUnit.get(i)?.setControlGroupNumber(void 0)}}class BoxedVar{constructor(e){this._onChange=new EventDispatcher,this.value=e}get value(){return this._value}set value(e){var t=e!==this._value;this._value=e,t&&this._onChange.dispatch(this,e)}get onChange(){return this._onChange.asEvent()}}class Player{get credits(){return this._credits}set credits(e){if(e<0)throw new RangeError("Can't set credits to a negative value");this._credits=e}constructor(e,t=void 0,i,r=new Color(255,0,0)){this.name=e,this.country=t,this.startLocation=i,this.color=r,this.isAi=!1,this.defeated=!1,this.resigned=!1,this.dropped=!1,this.objectsByType=new Map,this.objectsById=new Map,this.traits=new Traits,this._credits=0,this.score=0,this.limitedUnitsBuiltByName=new Map,this.unitsBuiltByType=new Map,this.unitsKilledByType=new Map,this.unitsLostByType=new Map,this.buildingsCaptured=0,this.cratesPickedUp=0,this.creditsGained=0,this.cheerCooldownTicks=0,this.isObserver=!t,this.isNeutral=!!t&&!t.isPlayable()}getOrCreateObjectsForType(e){let t=this.objectsByType.get(e);return t||(t=new Set,this.objectsByType.set(e,t)),t}addOwnedObject(e){let t=this.getOrCreateObjectsForType(e.type);t.add(e),(e.owner=this).objectsById.set(e.id,e)}removeOwnedObject(e){let t=this.objectsByType.get(e.type);if(!t||!t.has(e))throw new Error(`GameObject ${e.name} does not belong to player `+this.name);t.delete(e),this.objectsById.delete(e.id)}getOwnedObjectById(e){return this.objectsById.get(e)}getOwnedObjectsByType(e,t=!1){let i=[];return i=[...this.objectsByType.get(e)||new Set],t||(i=i.filter(e=>!e.limboData)),i}getOwnedObjects(e=!1){let t=[];return[...this.objectsByType.values()].forEach(e=>{e.forEach(e=>t.push(e))}),e||(t=t.filter(e=>!e.limboData)),t}removeAllOwnedObjects(){this.objectsByType.forEach(e=>e.clear()),this.objectsById.clear()}get buildings(){return this.getOrCreateObjectsForType(ObjectType.Building)}addUnitsBuilt(e,t){this.unitsBuiltByType.set(e.type,(this.unitsBuiltByType.get(e.type)??0)+t),e.buildLimit<0&&this.limitedUnitsBuiltByName.set(e.name,(this.limitedUnitsBuiltByName.get(e.name)??0)+t)}getUnitsBuilt(e){return void 0!==e?this.unitsBuiltByType.get(e)??0:[...this.unitsBuiltByType.values()].reduce((e,t)=>e+t,0)}getLimitedUnitsBuilt(e){return this.limitedUnitsBuiltByName.get(e)??0}addUnitsKilled(e,t){this.unitsKilledByType.set(e,(this.unitsKilledByType.get(e)??0)+t)}getUnitsKilled(e){return void 0!==e?this.unitsKilledByType.get(e)??0:[...this.unitsKilledByType.values()].reduce((e,t)=>e+t,0)}addUnitsLost(e,t){this.unitsLostByType.set(e,(this.unitsLostByType.get(e)??0)+t)}getUnitsLost(e){return void 0!==e?this.unitsLostByType.get(e)??0:[...this.unitsLostByType.values()].reduce((e,t)=>e+t,0)}isCombatant(){return!this.isNeutral&&!this.isObserver&&!this.defeated}canProduceVeteran(e){if(!this.production||!this.country)throw new Error("Non-combatants can't produce units");var t=this.production.getQueueTypeForObject(e),t=this.production.getFactoryTypeForQueueType(t);return this.production.hasVeteranType(t)||this.country.hasVeteranUnit(e.type,e.name)}getHash(){return fnv32a([this.credits,...this.traits.getAll().map(e=>e.getHash?.()??0)])}debugGetState(){return{name:this.name,credits:this.credits,traits:this.traits.getAll().reduce((e,t)=>{var i=t.debugGetState?.();return void 0!==i&&(e[t.constructor.name]=i),e},{})}}dispose(){this.traits.dispose(),this.production?.dispose()}}class RadarTrait{constructor(){this.disabled=!0,this.activeEvents=[]}isDisabled(){return this.disabled}setDisabled(e){this.disabled=e}}const prereqCategIniVals=(new Map).set("POWER",PrereqCategory.Power).set("FACTORY",PrereqCategory.Factory).set("BARRACKS",PrereqCategory.Barracks).set("RADAR",PrereqCategory.Radar).set("TECH",PrereqCategory.Tech).set("PROC",PrereqCategory.Proc);class Production{static factory(e,t,i,r){let s=new Production(e,t.mpDialogSettings.techLevel,i,t,r);t=t.general.maximumQueuedObjects+1;return s.addQueue(QueueType.Structures,new ProductionQueue(QueueType.Structures,1,1)),s.addQueue(QueueType.Armory,new ProductionQueue(QueueType.Armory,1,1)),s.addQueue(QueueType.Infantry,new ProductionQueue(QueueType.Infantry,t,t)),s.addQueue(QueueType.Vehicles,new ProductionQueue(QueueType.Vehicles,t,t)),s.addQueue(QueueType.Ships,new ProductionQueue(QueueType.Ships,t,t)),s.addQueue(QueueType.Aircrafts,new ProductionQueue(QueueType.Aircrafts,0,t)),s}constructor(e,t,i,r,s){this.player=e,this.maxTechLevel=t,this.gameOpts=i,this.rules=r,this.allAvailableObjects=s,this.buildSpeedModifier=1,this.queues=new Map,this._onQueueUpdate=new EventDispatcher,this.primaryFactories=new Map,this.factoryCounts=new Map,this.veteranTypes=new Set,this.stolenTech=new Set}get onQueueUpdate(){return this._onQueueUpdate.asEvent()}addQueue(e,t){this.queues.set(e,t),t.onUpdate.subscribe(()=>this._onQueueUpdate.dispatch(this,t))}getQueue(e){var t=this.queues.get(e);if(!t)throw new Error("No queue found with type "+QueueType[e]);return t}getAllQueues(){return[...this.queues.values()]}getQueueTypeForObject(e){if(e.type===ObjectType.Building)return e.buildCat===BuildCat.Combat?QueueType.Armory:QueueType.Structures;if(e.type===ObjectType.Infantry)return QueueType.Infantry;if(e.type===ObjectType.Vehicle)return e.naval?QueueType.Ships:QueueType.Vehicles;if(e.type===ObjectType.Aircraft)return QueueType.Aircrafts;throw new Error("Unsupported object type "+ObjectType[e.type])}getQueueForObject(e){return this.getQueue(this.getQueueTypeForObject(e))}getQueueTypeForFactory(e){if(e===FactoryType.InfantryType)return QueueType.Infantry;if(e===FactoryType.UnitType)return QueueType.Vehicles;if(e===FactoryType.AircraftType)return QueueType.Aircrafts;if(e===FactoryType.NavalUnitType)return QueueType.Ships;throw new Error("Unsupported factory type "+FactoryType[e])}getFactoryTypeForQueueType(e){if(e===QueueType.Structures||e===QueueType.Armory)return FactoryType.BuildingType;if(e===QueueType.Infantry)return FactoryType.InfantryType;if(e===QueueType.Vehicles)return FactoryType.UnitType;if(e===QueueType.Aircrafts)return FactoryType.AircraftType;if(e===QueueType.Ships)return FactoryType.NavalUnitType;throw new Error("Unsupported queue type "+QueueType[e])}getQueueForFactory(e){return this.getQueue(this.getQueueTypeForFactory(e))}isAvailableForProduction(e){return-1!==e.techLevel&&e.techLevel<=this.maxTechLevel&&!(0===e.buildLimit&&!this.player.isAi)&&!(e.superWeapon&&this.rules.getSuperWeapon(e.superWeapon).disableableFromShell&&!this.gameOpts.superWeapons)&&this.hasFactoryFor(e)&&this.meetsPrerequisites(e)}getAvailableObjects(){return this.allAvailableObjects.filter(e=>this.isAvailableForProduction(e))}hasFactoryFor(i){if(i.owner.length){let t=this.getFactoryTypeFor(i);return!![...this.player.buildings].find(e=>e.factoryTrait?.type===t&&(t!==FactoryType.UnitType||e.rules.naval===i.naval)&&!!e.rules.owner.find(e=>i.owner.includes(e)))}return!0}meetsStolenTech(e){return e.requiresStolenAlliedTech?this.stolenTech.has(SideType.GDI):e.requiresStolenSovietTech?this.stolenTech.has(SideType.Nod):!e.requiresStolenThirdTech||this.stolenTech.has(SideType.ThirdSide)}getFactoryTypeFor(e){return e.type===ObjectType.Building?FactoryType.BuildingType:e.type===ObjectType.Infantry?FactoryType.InfantryType:e.type===ObjectType.Aircraft?FactoryType.AircraftType:e.naval?FactoryType.NavalUnitType:FactoryType.UnitType}meetsPrerequisites(e){let t=[...this.player.buildings].map(e=>e.name);for(var i of e.prerequisiteOverride)if(i=i.toUpperCase(),t.includes(i))return!0;if(!e.isAvailableTo(this.player.country))return!1;var r;for(r of e.prerequisite)if(r=r.toUpperCase(),prereqCategIniVals.has(r)){var s=prereqCategIniVals.get(r);if(void 0===s)throw new Error("Unknown prereqName "+r);var a,n=this.rules.general.prereqCategories.get(s);if(void 0===n)throw new Error(`Missing prerequisite category ${s} in rules`);let e=!1;for(a of n)if(-1!==t.indexOf(a)){e=!0;break}if(!e)return!1}else if(-1===t.indexOf(r))return!1;return!!this.meetsStolenTech(e)}getPrimaryFactory(e){return this.primaryFactories.get(e)}setPrimaryFactory(e){e.rules.factory&&this.primaryFactories.set(e.rules.factory,e)}isPrimaryFactory(e){return this.getPrimaryFactory(e.rules.factory)===e}incrementFactoryCount(e){this.factoryCounts.set(e,(this.factoryCounts.get(e)??0)+1)}decrementFactoryCount(e){if(!this.factoryCounts.get(e))throw new Error(`Can't decrement factory count ${FactoryType[e]}. Already 0`);this.factoryCounts.set(e,this.factoryCounts.get(e)-1)}getFactoryCount(e){return this.factoryCounts.get(e)??0}crownPrimaryFactoryHeir(t){var e=[...this.player.buildings].find(e=>e.rules.factory===t);e?this.primaryFactories.set(t,e):this.primaryFactories.delete(t)}hasAnyFactory(){return 0<this.primaryFactories.size}addVeteranType(e){this.veteranTypes.add(e)}hasVeteranType(e){return this.veteranTypes.has(e)}addStolenTech(e){this.stolenTech.add(e)}dispose(){this.queues.clear(),this.player=void 0}}class SuperWeaponsTrait_SuperWeaponsTrait{constructor(){this.superWeapons=new Map}getAll(){return[...this.superWeapons.values()]}add(e){this.superWeapons.set(e.name,e)}has(e){return this.superWeapons.has(e)}get(e){return this.superWeapons.get(e)}remove(e){this.superWeapons.delete(e)}}class SharedDetectDisguiseTrait{constructor(){this.objects=new Set}add(e){this.objects.add(e)}delete(e){this.objects.delete(e)}has(e){return this.objects.has(e)}dispose(){this.objects.clear()}}class PlayerFactory{constructor(e,t,i){this.rules=e,this.gameOpts=t,this.allAvailableObjects=i}createCombatant(e,t,i,r,s,a){let n=new Player(e,t,i,r);return n.isAi=s,n.aiDifficulty=a,n.powerTrait=new PowerTrait(n),n.traits.add(n.powerTrait),n.radarTrait=new RadarTrait,n.traits.add(n.radarTrait),n.superWeaponsTrait=new SuperWeaponsTrait_SuperWeaponsTrait,n.traits.add(n.superWeaponsTrait),n.production=Production.factory(n,this.rules,this.gameOpts,this.allAvailableObjects),n.sharedDetectDisguiseTrait=new SharedDetectDisguiseTrait,n}createObserver(e,t){let i=new Player(e,void 0,void 0,t.colors.get("LightGrey"));return i.radarTrait=new RadarTrait,i.traits.add(i.radarTrait),i.radarTrait.setDisabled(!1),i}createNeutral(e,t){var i=[...e.countryRules.values()].find(e=>e.side===SideType.Civilian);if(!i)throw new Error("Missing neutral country. No country found in rules with Civilian side");i=new Country(i);let r=new Player(t,i,void 0,e.colors.get("LightGrey"));return r.powerTrait=new PowerTrait(r),r.traits.add(r.powerTrait),r}}(NotifySpawn_NotifySpawn=NotifySpawn_NotifySpawn||{}).onSpawn=Symbol(),(NotifyUnspawn_NotifyUnspawn=NotifyUnspawn_NotifyUnspawn||{}).onUnspawn=Symbol(),(NotifyOwnerChange_NotifyOwnerChange=NotifyOwnerChange_NotifyOwnerChange||{}).onChange=Symbol();class PowerTrait_PowerTrait{[NotifySpawn_NotifySpawn.onSpawn](e,t){e.isTechno()&&e.rules.power&&!this.isCapturablePower(e,e.owner)&&e.owner.powerTrait?.updateFrom(e,"add",t)}[NotifyUnspawn_NotifyUnspawn.onUnspawn](e,t){e.isTechno()&&e.rules.power&&!e.warpedOutTrait.isActive()&&!this.isCapturablePower(e,e.owner)&&e.owner.powerTrait?.updateFrom(e,"remove",t)}[NotifyHealthChange.onChange](e,t){e.isTechno()&&e.rules.power&&!e.warpedOutTrait.isActive()&&!this.isCapturablePower(e,e.owner)&&e.owner.powerTrait?.updateFrom(e,"update",t)}[NotifyOwnerChange_NotifyOwnerChange.onChange](e,t,i){e.rules.power&&!e.warpedOutTrait.isActive()&&(this.isCapturablePower(e,t)||t.powerTrait?.updateFrom(e,"remove",i),this.isCapturablePower(e,e.owner)||e.owner.powerTrait?.updateFrom(e,"add",i))}[NotifyWarpChange.onChange](e,t,i){e.rules.power&&!this.isCapturablePower(e,e.owner)&&e.owner.powerTrait?.updateFrom(e,i?"remove":"add",t)}[NotifyTick.onTick](e){for(var t of e.getCombatants())t.powerTrait.updateBlackout(e)}isCapturablePower(e,t){return 0<e.rules.power&&t.isNeutral&&e.rules.needsEngineer}}class ObjectSellEvent{constructor(e){this.target=e,this.type=EventType.ObjectSell}}class SellTrait{constructor(e,t){this.game=e,this.generalRules=t}sell(t){if(!t.isBuilding()||!t.rules.unsellable){let e=this.computeRefundValue(t);e&&(t.rules.wall&&(e=0),t.traits.filter(NotifySell).forEach(e=>{e[NotifySell.onSell](t,this.game)}),t.isBuilding()?this.game.getConstructionWorker(t.owner).unplace(t,()=>this.afterObjectUnspawned(t,e)):(this.game.unspawnObject(t),this.afterObjectUnspawned(t,e)))}}afterObjectUnspawned(e,t){e.owner.credits+=t,this.game.events.dispatch(new ObjectSellEvent(e)),e.dispose()}computeRefundValue(e){let t=0;return 0<e.rules.soylent?t=e.rules.soylent:e.rules.cost&&(t=e.purchaseValue,e.owner.isAi||(t=Math.floor(t*this.generalRules.refundPercent))),t}computePurchaseValue(e,t){return e.cost}dispose(){this.game=void 0}}class RadarOnOffEvent{constructor(e,t){this.target=e,this.radarEnabled=t,this.type=EventType.RadarOnOff}}class RadarEvent{constructor(e,t,i){this.target=e,this.radarEventType=t,this.tile=i,this.type=EventType.RadarEvent}}class RadarTrait_RadarTrait{constructor(){this.activeLightningStrikes=new Map}[NotifySpawn_NotifySpawn.onSpawn](e,t){e.isBuilding()&&e.rules.radar&&this.updateRadarForPlayer(e.owner,t)}[NotifyUnspawn_NotifyUnspawn.onUnspawn](e,t){e.isBuilding()&&e.rules.radar&&this.updateRadarForPlayer(e.owner,t)}[NotifyPower.onPowerLow](e,t){this.updateRadarForPlayer(e,t)}[NotifyPower.onPowerRestore](e,t){this.updateRadarForPlayer(e,t)}[NotifyPower.onPowerChange](){}[NotifyOwnerChange_NotifyOwnerChange.onChange](e,t,i){e.rules.radar&&(this.updateRadarForPlayer(t,i),this.updateRadarForPlayer(e.owner,i))}[NotifyWarpChange.onChange](e,t){e.rules.radar&&this.updateRadarForPlayer(e.owner,t)}[NotifySuperWeaponActivate.onActivate](e,t,i){if(e===SuperWeaponType.LightningStorm){this.activeLightningStrikes.set(t,(this.activeLightningStrikes.get(t)??0)+1);for(var r of i.getCombatants())r===t||i.alliances.areAllied(r,t)||this.updateRadarForPlayer(r,i)}}[NotifySuperWeaponDeactivate.onDeactivate](e,t,i){if(e===SuperWeaponType.LightningStorm){e=(this.activeLightningStrikes.get(t)??0)-1;if(0<e?this.activeLightningStrikes.set(t,e):this.activeLightningStrikes.delete(t),e<=0)for(var r of i.getCombatants())this.updateRadarForPlayer(r,i)}}updateRadarForPlayer(i,r){var e,t;i.radarTrait&&(e=i.radarTrait?.isDisabled(),t=![...i.buildings].find(e=>e.rules.radar&&!e.warpedOutTrait.isActive())||i.powerTrait.level===PowerLevel.Low||[...this.activeLightningStrikes.entries()].some(([e,t])=>t&&e!==i&&!r.alliances.areAllied(e,i)),i.radarTrait.setDisabled(t),e!==t&&r.events.dispatch(new RadarOnOffEvent(i,!t)))}[NotifyAttack_NotifyAttack.onAttack](e,t,i){e.isTechno()&&(!e.isBuilding()||e.rules.canBeOccupied||e.rules.needsEngineer?e.isVehicle()&&e.harvesterTrait&&this.addEventForPlayer(RadarEventType.HarvesterUnderAttack,e.owner,e.tile,i):this.addEventForPlayer(RadarEventType.BaseUnderAttack,e.owner,e.tile,i))}addEventForPlayer(r,e,s,a){let n=e.radarTrait;if(n){let t=a.rules.general.radar;n.activeEvents=n.activeEvents.filter(e=>a.currentTick-e.startTick<t.getEventDuration(e.type));let i=new RangeHelper(a.map.tileOccupation);!!n.activeEvents.find(e=>e.type===r&&i.isInTileRange(s,e.tile,0,t.getEventSuppresionDistance(e.type)))||(n.activeEvents.push({startTick:a.currentTick,tile:s,type:r}),a.events.dispatch(new RadarEvent(e,r,s)))}}}class InsufficientFundsEvent{constructor(e){this.target=e,this.type=EventType.InsufficientFunds}}const SIDEBAR_CLOCK_FRAMES=55;class ProductionTrait{constructor(e,t){this.rules=e,this.speedCheat=t,this.availableObjectRules=new Set;t=60*e.general.buildSpeed*GameSpeed.BASE_TICKS_PER_SECOND;this.baseBuildSpeed=1/(t/1e3),[...e.buildingRules.values(),...e.infantryRules.values(),...e.vehicleRules.values(),...e.aircraftRules.values()].forEach(e=>{e.owner.length&&this.availableObjectRules.add(e)})}[NotifyTick.onTick](e){for(var t of e.getCombatants())for(var i of t.production.getAllQueues())this.tickQueue(i,t,e)}[NotifySpawn_NotifySpawn.onSpawn](e,t){var i;e.isBuilding()&&e.owner.production?(i=e.rules.factory)&&(e.owner.production.getPrimaryFactory(i)||e.owner.production.setPrimaryFactory(e),e.owner.production.incrementFactoryCount(i),i===FactoryType.AircraftType&&this.updateAircraftQueueMaxSize(e.owner,t)):e.isAircraft()&&e.owner.production&&this.rules.general.padAircraft.includes(e.name)&&this.updateAircraftQueueMaxSize(e.owner,t)}[NotifyUnspawn_NotifyUnspawn.onUnspawn](e,t){var i;e.isBuilding()&&e.owner.production?(this.ensurePrerequisites(e.owner),(i=e.rules.factory)&&(e.owner.production.getPrimaryFactory(i)===e&&e.owner.production.crownPrimaryFactoryHeir(i),e.owner.production.decrementFactoryCount(i),i===FactoryType.AircraftType&&this.updateAircraftQueueMaxSize(e.owner,t))):e.isAircraft()&&e.owner.production&&this.rules.general.padAircraft.includes(e.name)&&this.updateAircraftQueueMaxSize(e.owner,t)}[NotifyOwnerChange_NotifyOwnerChange.onChange](e,t,i){var r;e.isBuilding()?(this.ensurePrerequisites(t),(r=e.rules.factory)&&(t.production?.getPrimaryFactory(r)===e&&t.production.crownPrimaryFactoryHeir(r),e.owner.production&&!e.owner.production.getPrimaryFactory(r)&&e.owner.production.setPrimaryFactory(e),t.production?.decrementFactoryCount(r),e.owner.production?.incrementFactoryCount(r),r===FactoryType.AircraftType&&(this.updateAircraftQueueMaxSize(e.owner,i),this.updateAircraftQueueMaxSize(t,i)))):e.isAircraft()&&this.rules.general.padAircraft.includes(e.name)&&(this.updateAircraftQueueMaxSize(e.owner,i),this.updateAircraftQueueMaxSize(t,i))}[NotifyPower.onPowerLow](e){e.production&&(e.production.buildSpeedModifier=this.computeLowPowerBuildSpeedModifier(e.powerTrait.power,e.powerTrait.drain))}[NotifyPower.onPowerRestore](e){e.production&&(e.production.buildSpeedModifier=1)}[NotifyPower.onPowerChange](e){e.powerTrait?.level===PowerLevel.Low&&e.production&&(e.production.buildSpeedModifier=this.computeLowPowerBuildSpeedModifier(e.powerTrait.power,e.powerTrait.drain))}computeLowPowerBuildSpeedModifier(e,t){e=1-Math.min(1,e/t),t=this.rules.general;return clamp(1-.3*t.lowPowerPenaltyModifier*e/.15,t.minLowPowerProductionSpeed,t.maxLowPowerProductionSpeed)}updateAircraftQueueMaxSize(i,r){i.production&&r.afterTick(()=>{var e=[...i.buildings].filter(e=>e.helipadTrait).reduce((e,t)=>e+t.dockTrait.numberOfDocks,0),t=i.getOwnedObjectsByType(ObjectType.Aircraft,!0).filter(e=>r.rules.general.padAircraft.includes(e.name)).length;i.production.getQueueForFactory(FactoryType.AircraftType).maxSize=Math.max(0,e-t)})}tickQueue(i,r,s){if(i.status===QueueStatus.Active){let e=!1,t=i.getFirst();var a,n=r.production.getFactoryTypeForQueueType(i.type),o=r.production.getFactoryCount(n),l=r.production.buildSpeedModifier,h=1/GameMath.pow(this.rules.general.multipleFactory,o-1),n=t.rules.wall?1/this.rules.general.wallBuildSpeedCoefficient:1,o=this.baseBuildSpeed*l*h*n,l=t.creditsEach,h=SIDEBAR_CLOCK_FRAMES-1,n=l&&!this.speedCheat.value?floorTo(l/o*t.rules.buildTimeMultiplier,h):h,n=Math.max(h,n),o=r.credits,h=t.creditsEach-t.creditsSpent,h=Math.min(r.credits,l/n+t.creditsSpentLeftover,h);0<h?(a=Math.floor(h),t.creditsSpentLeftover=h-a,a&&(t.creditsSpent+=a,t.progress=t.creditsSpent/t.creditsEach,r.credits-=a,e=!0)):t.creditsEach||(a=t.progress*n,t.progress=Math.min(1,(1+a)/n),e=!0),e&&1===t.progress&&(i.status=QueueStatus.Ready),0<o&&!r.credits&&s.events.dispatch(new InsufficientFundsEvent(r)),e&&i.notifyUpdated()}}ensurePrerequisites(e){if(e.production)for(var t of e.production.getAllQueues()){var i;for(i of t.getAll().map(e=>({rules:e.rules,quantity:e.quantity,creditsSpent:e.creditsSpent})))e.production.isAvailableForProduction(i.rules)||(t.pop(i.rules,i.quantity),e.credits+=i.creditsSpent)}}getAvailableObjects(){return[...this.availableObjectRules]}}(NotifyAllianceChange=NotifyAllianceChange||{}).onChange=Symbol();class MapShroudTrait{constructor(e,t){this.map=e,this.alliances=t,this.shroudByPlayer=new Map,this.revealedToAll=new Set,this.gapGenerators=new Set,this.handleTileOccupationUpdate=({object:e,type:t})=>{if("removed"!==t&&e.isTechno()){var i,t=e.owner;for(i of[t,...this.alliances.getAllies(t)])this.shroudByPlayer.get(i)?.revealFrom(e)}}}getPlayerShroud(e){return this.shroudByPlayer.get(e)}init(t){t.map.tileOccupation.onChange.subscribe(this.handleTileOccupationUpdate);let i=(new MapShroud).fromTiles(this.map.tiles);for(var r of t.getCombatants()){let e=i.clone();this.shroudByPlayer.set(r,e),this.revealObjects(e,r,t),e.update()}}[NotifyElevationChange.onElevationChange](e,t,i){if(Math.floor(e.tileElevation)!==Math.floor(i)){var r,i=e.owner;for(r of[i,...this.alliances.getAllies(i)])this.shroudByPlayer.get(r)?.revealFrom(e)}}[NotifyTick.onTick](e){for(var[t,i]of this.shroudByPlayer)t.defeated&&!t.isObserver?this.shroudByPlayer.delete(t):i.update()}[NotifyOwnerChange_NotifyOwnerChange.onChange](e,t,i){if(e.isBuilding()&&e.rules.spySat&&(this.revealMap(e.owner,i),t.getOwnedObjectsByType(ObjectType.Building).find(e=>e.rules.spySat)||this.resetShroud(t,i)),e.isSpawned)for(var r of[e.owner,...i.alliances.getAllies(e.owner)])this.shroudByPlayer.get(r)?.revealFrom(e)}[NotifyAllianceChange.onChange](t,e,i){if(e){let e=this.getPlayerShroud(t.players.first);var r,s,t=i.alliances.getAllies(t.players.first).map(e=>this.getPlayerShroud(e)).filter(isNotNullOrUndefined);for(r of t)e.merge(r);e.invalidateFull();for(s of t)s.copy(e),s.invalidateFull()}}[NotifySpawn_NotifySpawn.onSpawn](e,t){if(e.isBuilding()){if(e.rules.spySat&&this.revealMap(e.owner,t),e.rules.revealToAll){this.revealedToAll.add(e);for(var i of t.getCombatants())i===e.owner||t.alliances.areAllied(e.owner,i)||(this.shroudByPlayer.get(i)?.revealObject(e),t.traits.get(RadarTrait_RadarTrait).addEventForPlayer(RadarEventType.EnemyObjectSensed,i,e.centerTile,t))}e.gapGeneratorTrait&&this.gapGenerators.add(e)}}[NotifyUnspawn_NotifyUnspawn.onUnspawn](e,t){e.isBuilding()&&(e.rules.spySat&&(e.owner.getOwnedObjectsByType(ObjectType.Building).find(e=>e.rules.spySat)||this.resetShroud(e.owner,t)),e.rules.revealToAll&&this.revealedToAll.delete(e),e.gapGeneratorTrait&&this.gapGenerators.delete(e))}[NotifyPower.onPowerLow](e,t){this.updateGaps(t,e)}[NotifyPower.onPowerRestore](e,t){this.updateGaps(t,e)}[NotifyPower.onPowerChange](e,t){}revealMap(e,t){this.shroudByPlayer.get(e)?.revealAll(),this.markOwnGapTiles(t,e),this.updateGaps(t)}resetShroud(e,t){let i=this.shroudByPlayer.get(e);i&&(i.reset(),this.markOwnGapTiles(t,e),this.revealObjects(i,e,t))}revealObjects(t,e,i){var r;for(r of[...e.getOwnedObjects(),...i.alliances.getAllies(e).map(e=>e.getOwnedObjects()).flat()])t.revealFrom(r);this.revealedToAll.forEach(e=>t.revealObject(e))}updateGaps(e,t){for(var i of this.gapGenerators)t&&i.owner!==t||i.gapGeneratorTrait.update(i,e)}markOwnGapTiles(e,t){for(var i of this.gapGenerators)i.owner!==t&&!e.alliances.areAllied(i.owner,t)||this.getPlayerShroud(t)?.toggleFlagsAround(i.tile,i.gapGeneratorTrait.radiusTiles,ShroudFlag.Darken,!0)}dispose(){this.map.tileOccupation.onChange.unsubscribe(this.handleTileOccupationUpdate)}}class PackBuildingTask extends Task{constructor(e){super(),this.game=e}onTick(e){return!(e.buildStatus!==BuildStatus.BuildDown&&(e.setBuildStatus(BuildStatus.BuildDown,this.game),!e.rules.wall))||(this.children.push(new WaitMinutesTask(this.game.rules.general.buildupTime)),!1)}}const isLegacyDisposable=e=>!e.dispose;class CompositeDisposable{constructor(){this.disposables=new Set}add(...e){e.map(e=>this.disposables.add("function"==typeof e?{dispose:e}:e))}remove(...e){e.map(e=>this.disposables.delete(e))}dispose(){this.disposables.forEach(e=>{"function"==typeof e?e():isLegacyDisposable(e)?e.destroy():e.dispose()}),this.disposables.clear()}}class ConstructionWorker{constructor(e,t,i,r,s){this.player=e,this.rules=t,this.art=i,this.map=r,this.game=s,this.adjacencyMaps=new Map,this.disposables=new CompositeDisposable;let a=({object:e})=>{e.isBuilding()&&this.adjacencyMaps.clear()};this.map.tileOccupation.onChange.subscribe(a),this.disposables.add(()=>this.map.tileOccupation.onChange.unsubscribe(a)),this.disposables.add(this.game.events.subscribe(EventType.AllianceChange,()=>this.adjacencyMaps.clear()),this.game.events.subscribe(EventType.ObjectOwnerChange,e=>{e.target.isBuilding()&&this.adjacencyMaps.clear()}),this.game.events.subscribe(EventType.ObjectDestroy,e=>{e.target.isBuilding()&&e.target.rules.leaveRubble&&this.adjacencyMaps.clear()}))}getAdjacentRect(e,t,i){return{x:e.rx-i,y:e.ry-i,width:t.width+2*i,height:t.height+2*i}}getAdjacencyMap(e){var t;let i=[];for(t of[...this.player.buildings,...this.game.gameOpts.buildOffAlly?this.game.alliances.getAllies(this.player).map(e=>[...e.buildings].filter(e=>e.rules.eligibileForAllyBuilding)).flat():[]])t.rules.baseNormal&&i.push(this.getAdjacentRect(t.tile,t.art.foundation,e));return i}meetsAdjacency(e,t){let i=this.adjacencyMaps.get(t);i||(i=this.getAdjacencyMap(t),this.adjacencyMaps.set(t,i));for(var r of i)if(rectIntersect(e,r))return!0;return!1}getPlacementPreview(e,t,i={}){var{normalizedTile:r=!1,ignoreObjects:s,ignoreAdjacent:i=!1}=i,a=this.rules.getBuilding(e),e=this.art.getObject(e,ObjectType.Building);let n=[];var o=e.foundation,l=r?t:this.normalizePlacementTileCoords(e,t);let h=!0;t={x:l.rx,y:l.ry,width:o.width,height:o.height};i||this.meetsAdjacency(t,a.adjacent)||(h=!1);for(let t=0;t<o.width;t++)for(let e=0;e<o.height;e++){var c={x:l.rx+t,y:l.ry+e},u=this.map.tiles.getByMapCoords(c.x,c.y);u&&n.push({rx:c.x,ry:c.y,buildable:h&&this.isTileBuildable(u,a,s)})}if(a.wall&&n[0].buildable){let e=this.getWallConnectingTiles(l,a);e.forEach(e=>{n.push({rx:e.rx,ry:e.ry,buildable:!0})})}return n}canPlaceAt(e,t,i={}){var{normalizedTile:r=!1,ignoreObjects:s,ignoreAdjacent:i=!1}=i,a=this.rules.getBuilding(e),e=this.art.getObject(e,ObjectType.Building),n=e.foundation,o=r?t:this.normalizePlacementTileCoords(e,t),t={x:o.rx,y:o.ry,width:n.width,height:n.height};if(!i&&!this.meetsAdjacency(t,a.adjacent))return!1;for(let t=0;t<n.width;t++)for(let e=0;e<n.height;e++){var l={x:o.rx+t,y:o.ry+e},l=this.map.tiles.getByMapCoords(l.x,l.y);if(!l||!this.isTileBuildable(l,a,s))return!1}return!0}placeAt(e,t,i=!1){let r=[],s=this.rules.getBuilding(e),a=i?t:this.normalizePlacementTile(e,t);if(s.wall){let t=[[a,s]],e=this.getWallConnectingTiles(a,s);e.forEach(e=>{e!==a&&t.push([e,s])});for(var n of t)r.push(this.executePlacement(n[0],n[1]))}else{var o,t=this.executePlacement(a,s);r.push(t);for(o of this.map.tileOccupation.calculateTilesForGameObject(a,t)){var l=this.map.getObjectsOnTile(o).find(e=>e.isSmudge());l&&this.game.unspawnObject(l)}}return r}normalizePlacementTileCoords(e,t){e=e.foundationCenter;return{rx:t.rx-e.x,ry:t.ry-e.y}}normalizePlacementTile(e,t){e=this.art.getObject(e,ObjectType.Building),e=this.normalizePlacementTileCoords(e,t),t=this.map.tiles.getByMapCoords(e.rx,e.ry);if(!t)throw new Error(`Can't build outside map (${e.rx}, ${e.ry})`);return t}unplace(e,t){e.unitOrderTrait.cancelAllTasks(),e.unitOrderTrait.addTasks(new TaskGroup(new PackBuildingTask(this.game),new CallbackTask(()=>{this.game.unspawnObject(e),t()})).setCancellable(!1)),e.unitOrderTrait[NotifyTick_NotifyTick.onTick](e,this.game)}executePlacement(e,t){let i=this.game.createObject(ObjectType.Building,t.name);return this.game.changeObjectOwner(i,this.player),i.purchaseValue=this.game.sellTrait.computePurchaseValue(t,this.player),this.game.spawnObject(i,e),i}getWallConnectingTiles(i,r){var s,a=r.guardRange+1;let n=[];for(s of[[0,1],[0,-1],[1,0],[-1,0]]){let t=[];for(let e=0;e<a;++e){var o={x:i.rx+s[0]*e,y:i.ry+s[1]*e},o=this.map.tiles.getByMapCoords(o.x,o.y);if(!o)break;if(this.map.getObjectsOnTile(o).find(e=>e.isBuilding()&&e.name===r.name&&e.owner===this.player)){n=n.concat(t);break}if(!this.isTileBuildable(o,r))break;t.push(o)}}return n}isTileBuildable(e,t,i){return!!this.map.isWithinBounds(e)&&(!this.game.mapShroudTrait.getPlayerShroud(this.player)?.isShrouded(e)&&(!this.map.getGroundObjectsOnTile(e).some(e=>!(i?.includes(e)||e.isBuilding()&&e.rules.invisibleInGame||e.isSmudge()))&&(t.waterBound?0<this.rules.getLandRules(e.landType).getSpeedModifier(SpeedType.Float):0===e.rampType&&this.rules.getLandRules(e.landType).buildable)))}dispose(){this.disposables.dispose()}}class StartingUnitsGenerator{static generate(e,t,i,r){var s,a=i.reduce((e,t)=>e+t.cost,0)/i.length*e;let n=[],o=a,l=(i=i.filter(e=>e.isAvailableTo(r)&&e.hasOwner(r))).filter(e=>t.includes(e.name));for(s of l){if(o<=0)break;var h=2/3/l.length,h=Math.ceil(h*a/s.cost);o-=h*s.cost,n.push({name:s.name,type:ObjectType.Vehicle,count:h})}var c,i=i.filter(e=>!l.includes(e)),u=o/i.length;for(c of i){if(o<=0)break;var d=Math.ceil(u/c.cost);o-=d*c.cost,n.push({name:c.name,type:ObjectType.Infantry,count:d})}return n}}class GameEventBus{constructor(){this.dispatcher=new EventDispatcher,this.dispatchersByType=new Map}dispatch(e){this.dispatcher.dispatch(void 0,e),this.dispatchersByType.get(e.type)?.dispatch(void 0,e)}subscribe(e,t){let i=void 0,r;return r="function"==typeof e?e:(i=e,t),void 0===i?(this.dispatcher.subscribe(r),()=>this.unsubscribe(r)):this.subscribeType(i,r)}unsubscribe(e,t){let i=void 0,r;r="function"==typeof e?e:(i=e,t),void 0===i?this.dispatcher.unsubscribe(r):this.unsubscribeType(i,r)}subscribeType(e,t){let i=this.dispatchersByType.get(e);return i||(i=new EventDispatcher,this.dispatchersByType.set(e,i)),i.subscribe(t),()=>this.unsubscribeType(e,t)}unsubscribeType(e,t){this.dispatchersByType.get(e)?.unsubscribe(t)}}class ObjectDestroyEvent{constructor(e,t,i){this.target=e,this.attackerInfo=t,this.incidental=i,this.type=EventType.ObjectDestroy}}class PlayerDefeatedEvent{constructor(e){this.target=e,this.type=EventType.PlayerDefeated}}(NotifyDestroy_NotifyDestroy=NotifyDestroy_NotifyDestroy||{}).onDestroy=Symbol();class ObjectOwnerChangeEvent{constructor(e,t){this.target=e,this.prevOwner=t,this.type=EventType.ObjectOwnerChange}}class ObjectUnspawnEvent{constructor(e){this.gameObject=e,this.type=EventType.ObjectUnspawn}}class ObjectSpawnEvent{constructor(e){this.gameObject=e,this.type=EventType.ObjectSpawn}}!function(e){e[e.Requested=0]="Requested",e[e.Formed=1]="Formed",e[e.Broken=2]="Broken"}(AllianceEventType=AllianceEventType||{});class AllianceChangeEvent{constructor(e,t,i){this.alliance=e,this.changeType=t,this.from=i,this.type=EventType.AllianceChange}}var NotifyObjectTraitAdd,GameStatus,ActionType,NotifyPlaceBuilding,PointerType,OrderFeedbackType,EvacState,EnterHospitalTask_State,EnterTransportTask_State,UpdateType,DebugCommandType,mersenne_twister=__webpack_require__(804),mersenne_twister_default=__webpack_require__.n(mersenne_twister);class Prng{static factory(e,t){t=Number.isNaN(Number(e))?Crc32.calculateCrc(binaryStringToUint8Array(e)):Number(e+""+t);return new Prng(t)}constructor(e){this.prng=new(mersenne_twister_default())(e)}generateRandomInt(e,t){var i=this.prng.random();return this.lastRandom=i,Math.floor(i*(t-e+1))+e}generateRandom(){var e=this.prng.random();return this.lastRandom=e}getLastRandom(){return this.lastRandom}}class TriggerExecutor{constructor(e,t){this.action=e,this.trigger=t}getDebugName(){return`${this.action.triggerId}[${this.action.index}] (${this.trigger.name}).`}}class AddSuperWeaponExecutor extends TriggerExecutor{constructor(e,t,i){super(e,t),this.oneTimeOnly=i,this.superWeaponIdx=Number(e.params[1])}execute(i){var r=[...i.rules.superWeaponRules.values()].find(e=>e.index===this.superWeaponIdx);if(r){let t=i.getAllPlayers().find(e=>e.country?.name===this.trigger.houseName);if(t&&t.superWeaponsTrait&&!t.superWeaponsTrait.has(r.name)){let e=i.createSuperWeapon(r.name,t,this.oneTimeOnly);e.isGift=!0,t.superWeaponsTrait.add(e)}}else console.warn(`No superweapon found with index "${this.superWeaponIdx}". `+`Skipping action ${this.getDebugName()}.`)}}class ApplyDamageExecutor extends TriggerExecutor{constructor(e,t,i){super(e,t),this.damage=i}execute(t){var e=Number(this.action.params[1]),i=t.map.getTileAtWaypoint(e);if(i){var r=t.rules.getWarhead(Warhead.HE_WARHEAD_NAME);let e=new Warhead(r);var s=t.map.tileOccupation.getBridgeOnTile(i),a=s?.tileElevation??0,r=t.map.getTileZone(i);e.detonate(t,this.damage,i,a,Coords.tile3dToWorld(i.rx+.5,i.ry+.5,i.z+a),r,s?CollisionType.OnBridge:CollisionType.None,t.createTarget(s,i),void 0)}else console.warn(`No valid location found for waypoint ${e}. `+`Skipping action ${this.getDebugName()}.`)}}class ChangeHouseAllExecutor extends TriggerExecutor{execute(r){let t=r.getAllPlayers().find(e=>e.country?.name===this.trigger.houseName);if(t){let i=Number(this.action.params[1]),e;if(i>=ChangeHouseAllExecutor.locationHouseIdBegin&&i<ChangeHouseAllExecutor.locationHouseIdBegin+r.map.startingLocations.length){let t=i-ChangeHouseAllExecutor.locationHouseIdBegin;e=r.getAllPlayers().find(e=>e.startLocation===t)}else e=r.getAllPlayers().find(e=>e.country?.id===i);if(e)for(var s of t.getOwnedObjects(!0))r.changeObjectOwner(s,e)}}}ChangeHouseAllExecutor.locationHouseIdBegin=4475;class ChangeHouseExecutor extends TriggerExecutor{constructor(e,t){super(e,t),this.houseId=Number(e.params[1])}execute(e,t){let i;if(this.houseId>=ChangeHouseExecutor.locationHouseIdBegin&&this.houseId<ChangeHouseExecutor.locationHouseIdBegin+e.map.startingLocations.length){let t=this.houseId-ChangeHouseExecutor.locationHouseIdBegin;i=e.getAllPlayers().find(e=>e.startLocation===t)}else i=e.getAllPlayers().find(e=>e.country?.id===this.houseId);if(i)for(var r of t)r instanceof GameObject&&r.isSpawned&&e.changeObjectOwner(r,i)}}ChangeHouseExecutor.locationHouseIdBegin=4475;class CheerTask extends Task{constructor(){super(),this.executed=!1,this.cancellable=!1}onTick(e){return this.executed?(e.stance=StanceType.None,!0):!e.isInfantry()||!e.art.sequences.has(SequenceType.Cheer)||(e.stance!==StanceType.None&&e.stance!==StanceType.Guard||(e.stance=StanceType.Cheer,this.children.push(new WaitMinutesTask(1/60).setCancellable(!1)),!(this.executed=!0)))}}class CheerExecutor extends TriggerExecutor{constructor(e,t){super(e,t),this.houseId=Number(e.params[1])}execute(e){let t=e.getAllPlayers().filter(e=>e.country&&!e.defeated);if(-1!==this.houseId&&(t=t.filter(e=>e.country?.id===this.houseId)),t.length)for(var i of t[0].getOwnedObjectsByType(ObjectType.Infantry))i.unitOrderTrait.isIdle()&&i.unitOrderTrait.addTask(new CheerTask)}}const crateConfigs=new Map([[0,e=>{e=e.rules.powerups.powerups.find(e=>e.type===PowerupType.Money);return e?{...e,data:"5000"}:void 0}],[1,PowerupType.Unit],[2,PowerupType.HealBase],[3,PowerupType.Cloak],[4,PowerupType.Explosion],[5,PowerupType.Napalm],[6,PowerupType.Money],[7,PowerupType.Darkness],[8,PowerupType.Reveal],[9,PowerupType.Armor],[10,PowerupType.Speed],[11,PowerupType.Firepower],[12,PowerupType.ICBM],[13,void 0],[14,PowerupType.Veteran],[15,void 0],[16,PowerupType.Gas],[17,PowerupType.Tiberium],[18,void 0]]);class CreateCrateExecutor extends TriggerExecutor{execute(e){var t=Number(this.action.params[1]),i=this.action.params[6],r=e.map.getTileAtWaypoint(i);if(r)if(crateConfigs.has(t)){const s=crateConfigs.get(t);t="function"==typeof s?s(e):e.rules.powerups.powerups.find(e=>e.type===s);t&&e.crateGeneratorTrait.spawnCrateAt(r,t,e)}else e.crateGeneratorTrait.spawnRandomCrateAt(r,e);else console.warn(`No valid location found for waypoint ${i}. `+`Skipping action ${this.getDebugName()}.`)}}class CreateRadarEventExecutor extends TriggerExecutor{execute(e){var t=Number(this.action.params[1])-1;if(Object.values(RadarEventType).includes(t)){var i=this.action.params[6],r=e.map.getTileAtWaypoint(i);if(r)for(var s of e.getCombatants())e.traits.get(RadarTrait_RadarTrait).addEventForPlayer(t,s,r,e);else console.warn(`No valid location found for waypoint ${i}. `+`Skipping action ${this.getDebugName()}.`)}else console.warn(`Unknown radar event type "${1+t}". Skipping action ${this.getDebugName()}.`)}}class DestroyObjectExecutor extends TriggerExecutor{execute(e,t){for(var i of t)i instanceof GameObject&&i.isSpawned&&e.destroyObject(i)}}class DestroyTagExecutor extends TriggerExecutor{execute(e){var t=this.action.params[1];e.triggers.destroyTag(t)}}class DestroyTriggerExecutor extends TriggerExecutor{execute(e){var t=this.action.params[1];e.triggers.destroyTrigger(t)}}class DetonateWarheadExecutor extends TriggerExecutor{execute(r){var s=Number(this.action.params[1]),e=this.action.params[6],a=r.map.getTileAtWaypoint(e);if(a){let t;try{t=r.rules.getWeaponByInternalId(s)}catch(e){if(e instanceof RangeError)return void console.warn(`Weapon with internal ID "${s}" not found. `+`Skipping action ${this.getDebugName()}.`);throw e}let e;try{e=r.rules.getWarhead(t.warhead)}catch(e){return void console.warn(`Warhead "${t.warhead}" not found. `+`Skipping action ${this.getDebugName()}.`)}let i=new Warhead(e);var n=r.map.tileOccupation.getBridgeOnTile(a),o=n?.tileElevation??0,s=r.map.getTileZone(a);i.detonate(r,t.damage,a,o,Coords.tile3dToWorld(a.rx+.5,a.ry+.5,a.z+o),s,n?CollisionType.OnBridge:CollisionType.None,r.createTarget(n,a),void 0)}else console.warn(`No valid location found for waypoint ${e}. `+`Skipping action ${this.getDebugName()}.`)}}class EvictOccupiersExecutor extends TriggerExecutor{execute(e,t){for(var i of t)i instanceof GameObject&&i.isBuilding()&&i.garrisonTrait&&!i.isDestroyed&&i.garrisonTrait.evacuate(e)}}class FireSaleExecutor extends TriggerExecutor{constructor(e,t){super(e,t),this.houseId=Number(e.params[1])}execute(e){var t=e.getAllPlayers().find(e=>e.country?.id===this.houseId);if(t)for(var i of t.buildings)e.sellTrait.sell(i)}}class ForceEndExecutor extends TriggerExecutor{execute(e){e.end()}}class ForceTriggerExecutor extends TriggerExecutor{execute(e){var t=this.action.params[1];e.triggers.forceTrigger(t,e)}}class GlobalVariableExecutor extends TriggerExecutor{constructor(e,t,i){super(e,t),this.value=i,this.variableIdx=Number(e.params[1])}execute(e){e.triggers.toggleGlobalVariable(this.variableIdx,this.value)}}class IronCurtainExecutor extends TriggerExecutor{execute(e){var t,i,r=this.action.params[6],s=e.map.getTileAtWaypoint(r);s?!(t=e.getAllPlayers().find(e=>!e.defeated&&e.country?.name===this.trigger.houseName))||(i=[...e.rules.superWeaponRules.values()].find(e=>e.type===SuperWeaponType.IronCurtain))&&e.traits.get(SuperWeaponsTrait).activateEffect(i,t,e,s,void 0,!0):console.warn(`No valid location found for waypoint ${r}. `+`Skipping action ${this.getDebugName()}.`)}}class LightningStrikeExecutor extends TriggerExecutor{execute(e){var t,i,r=this.action.params[6],s=e.map.getTileAtWaypoint(r);s?!(t=e.getAllPlayers().find(e=>!e.defeated&&e.country?.name===this.trigger.houseName))||(i=[...e.rules.superWeaponRules.values()].find(e=>e.type===SuperWeaponType.LightningStorm))&&e.traits.get(SuperWeaponsTrait).activateEffect(i,t,e,s,void 0,!0):console.warn(`No valid location found for waypoint ${r}. `+`Skipping action ${this.getDebugName()}.`)}}class LocalVariableExecutor extends TriggerExecutor{constructor(e,t,i){super(e,t),this.value=i,this.variableIdx=Number(e.params[1])}execute(e){e.triggers.toggleLocalVariable(this.variableIdx,this.value)}}class NoActionExecutor extends TriggerExecutor{execute(){}}class NukeStrikeExecutor extends TriggerExecutor{execute(e){var t,i,r=this.action.params[6],s=e.map.getTileAtWaypoint(r);s?!(t=e.getAllPlayers().find(e=>!e.defeated&&e.country?.name===this.trigger.houseName))||(i=[...e.rules.superWeaponRules.values()].find(e=>e.type===SuperWeaponType.MultiMissile))&&e.traits.get(SuperWeaponsTrait).activateEffect(i,t,e,s,void 0,!0):console.warn(`No valid location found for waypoint ${r}. `+`Skipping action ${this.getDebugName()}.`)}}class TriggerAnimEvent{constructor(e,t){this.name=e,this.tile=t,this.type=EventType.TriggerAnim}}class PlayAnimAtExecutor extends TriggerExecutor{execute(e){var t,i=this.action,r=Number(i.params[1]),s=e.rules.getAnimationName(r);void 0!==s?(t=i.params[6],(i=e.map.getTileAtWaypoint(t))?e.events.dispatch(new TriggerAnimEvent(s,i)):console.warn(`No valid location found for waypoint ${t}. `+`Skipping action ${this.getDebugName()}.`)):console.warn(`No animation found for index "${r}". Skipping action `+this.getDebugName())}}class TriggerSoundFxEvent{constructor(e,t){this.soundId=e,this.tile=t,this.type=EventType.TriggerSoundFx}}class PlaySoundFxAtExecutor extends TriggerExecutor{execute(e){var t=this.action,i=t.params[1],r=t.params[6],t=e.map.getTileAtWaypoint(r);t?e.events.dispatch(new TriggerSoundFxEvent(i,t)):console.warn(`No valid location found for waypoint ${r}. `+`Skipping action ${this.getDebugName()}.`)}}class PlaySoundFxExecutor extends TriggerExecutor{execute(e){e.events.dispatch(new TriggerSoundFxEvent(this.action.params[1]))}}class TriggerEvaEvent{constructor(e){this.soundId=e,this.type=EventType.TriggerEva}}class PlaySpeechExecutor extends TriggerExecutor{execute(e){e.events.dispatch(new TriggerEvaEvent(this.action.params[1]))}}class ReshroudMapExecutor extends TriggerExecutor{execute(e){for(var t of e.getCombatants())e.mapShroudTrait.resetShroud(t,e)}}class ResizePlayerViewExecutor extends TriggerExecutor{execute(e){var[t,i,r,s]=this.action.params.slice(2,6).map(Number);e.map.mapBounds.updateRawLocalSize({x:t,y:i,width:r,height:s})}}class RevealAroundWaypointExecutor extends TriggerExecutor{execute(e){var t=Number(this.action.params[1]),i=e.map.getTileAtWaypoint(t);if(i)for(var r of e.getCombatants())e.mapShroudTrait.getPlayerShroud(r)?.revealAround(i,e.rules.general.revealTriggerRadius);else console.warn(`No valid location found for waypoint ${t}. `+`Skipping action ${this.getDebugName()}.`)}}class RevealMapExecutor extends TriggerExecutor{execute(e){for(var t of e.getCombatants())e.mapShroudTrait.revealMap(t,e)}}class SellBuildingExecutor extends TriggerExecutor{execute(e,t){for(var i of t)i instanceof GameObject&&i.isBuilding()&&!i.isDestroyed&&e.sellTrait.sell(i)}}class SetAmbientLightExecutor extends TriggerExecutor{execute(e){var t=Number(this.action.params[1])/100;e.mapLightingTrait.setTargetAmbientIntensity(t)}}function int32ToFloat32(e){let t=new DataView(new ArrayBuffer(4));return t.setInt32(0,e),t.getFloat32(0)}class SetAmbientRateExecutor extends TriggerExecutor{execute(e){var t=int32ToFloat32(Number(this.action.params[1]));e.mapLightingTrait.setAmbientChangeRate(t)}}class SetAmbientStepExecutor extends TriggerExecutor{execute(e){var t=int32ToFloat32(Number(this.action.params[1]));e.mapLightingTrait.setAmbientChangeStep(t)}}class TriggerStopSoundFxEvent{constructor(e){this.tile=e,this.type=EventType.TriggerStopSoundFx}}class StopSoundFxAtExecutor extends TriggerExecutor{execute(e){var t=this.action.params[6],i=e.map.getTileAtWaypoint(t);i?e.events.dispatch(new TriggerStopSoundFxEvent(i)):console.warn(`No valid location found for waypoint ${t}. `+`Skipping action ${this.getDebugName()}.`)}}class TriggerTextEvent{constructor(e){this.label=e,this.type=EventType.TriggerText}}class TextTriggerExecutor extends TriggerExecutor{execute(e){e.events.dispatch(new TriggerTextEvent(this.action.params[1]))}}class TimerExtendExecutor extends TriggerExecutor{execute(e){e.countdownTimer.addSeconds(Number(this.action.params[1]))}}class TimerSetExecutor extends TriggerExecutor{execute(e){e.countdownTimer.setSeconds(Number(this.action.params[1]))}}class TimerShortenExecutor extends TriggerExecutor{execute(e){e.countdownTimer.addSeconds(-Number(this.action.params[1]))}}class TimerStartExecutor extends TriggerExecutor{execute(e){e.countdownTimer.start()}}class TimerStopExecutor extends TriggerExecutor{execute(e){e.countdownTimer.stop()}}class TimerTextExecutor extends TriggerExecutor{execute(e){e.countdownTimer.text=this.action.params[1]}}class ToggleTriggerExecutor extends TriggerExecutor{constructor(e,t,i){super(e,t),this.triggerEnable=i}execute(e){var t=this.action.params[1];e.triggers.setTriggerEnabled(t,this.triggerEnable)}}class TurnOnOffBuildingExecutor extends TriggerExecutor{constructor(e,t,i){super(e,t),this.turnOn=i}execute(e,t){for(var i of t)i instanceof GameObject&&i.isBuilding()&&i.poweredTrait?.setTurnedOn(this.turnOn)}}class UnrevealAroundWaypointExecutor extends TriggerExecutor{execute(e){var t=Number(this.action.params[1]),i=e.map.getTileAtWaypoint(t);if(i)for(var r of e.getCombatants())e.mapShroudTrait.getPlayerShroud(r)?.unrevealAround(i,e.rules.general.revealTriggerRadius);else console.warn(`No valid location found for waypoint ${t}. `+`Skipping action ${this.getDebugName()}.`)}}class TriggerExecutorFactory{create(e,t){switch(e.type){case TriggerActionType.NoAction:return new NoActionExecutor(e,t);case TriggerActionType.FireSale:return new FireSaleExecutor(e,t);case TriggerActionType.TextTrigger:return new TextTriggerExecutor(e,t);case TriggerActionType.DestroyTrigger:return new DestroyTriggerExecutor(e,t);case TriggerActionType.ChangeHouse:return new ChangeHouseExecutor(e,t);case TriggerActionType.RevealMap:return new RevealMapExecutor(e,t);case TriggerActionType.RevealAroundWaypoint:return new RevealAroundWaypointExecutor(e,t);case TriggerActionType.PlaySoundFx:return new PlaySoundFxExecutor(e,t);case TriggerActionType.PlaySpeech:return new PlaySpeechExecutor(e,t);case TriggerActionType.ForceTrigger:return new ForceTriggerExecutor(e,t);case TriggerActionType.TimerStart:return new TimerStartExecutor(e,t);case TriggerActionType.TimerStop:return new TimerStopExecutor(e,t);case TriggerActionType.TimerExtend:return new TimerExtendExecutor(e,t);case TriggerActionType.TimerShorten:return new TimerShortenExecutor(e,t);case TriggerActionType.TimerSet:return new TimerSetExecutor(e,t);case TriggerActionType.GlobalSet:return new GlobalVariableExecutor(e,t,!0);case TriggerActionType.GlobalClear:return new GlobalVariableExecutor(e,t,!1);case TriggerActionType.DestroyObject:return new DestroyObjectExecutor(e,t);case TriggerActionType.AddOneTimeSuperWeapon:return new AddSuperWeaponExecutor(e,t,!0);case TriggerActionType.AddRepeatingSuperWeapon:return new AddSuperWeaponExecutor(e,t,!1);case TriggerActionType.AllChangeHouse:return new ChangeHouseAllExecutor(e,t);case TriggerActionType.ResizePlayerView:return new ResizePlayerViewExecutor(e,t);case TriggerActionType.PlayAnimAt:return new PlayAnimAtExecutor(e,t);case TriggerActionType.DetonateWarhead:return new DetonateWarheadExecutor(e,t);case TriggerActionType.ReshroudMap:return new ReshroudMapExecutor(e,t);case TriggerActionType.EnableTrigger:return new ToggleTriggerExecutor(e,t,!0);case TriggerActionType.DisableTrigger:return new ToggleTriggerExecutor(e,t,!1);case TriggerActionType.CreateRadarEvent:return new CreateRadarEventExecutor(e,t);case TriggerActionType.LocalSet:return new LocalVariableExecutor(e,t,!0);case TriggerActionType.LocalClear:return new LocalVariableExecutor(e,t,!1);case TriggerActionType.SellBuilding:return new SellBuildingExecutor(e,t);case TriggerActionType.TurnOffBuilding:return new TurnOnOffBuildingExecutor(e,t,!1);case TriggerActionType.TurnOnBuilding:return new TurnOnOffBuildingExecutor(e,t,!0);case TriggerActionType.ApplyOneHundredDamage:return new ApplyDamageExecutor(e,t,100);case TriggerActionType.ForceEnd:return new ForceEndExecutor(e,t);case TriggerActionType.DestroyTag:return new DestroyTagExecutor(e,t);case TriggerActionType.SetAmbientStep:return new SetAmbientStepExecutor(e,t);case TriggerActionType.SetAmbientRate:return new SetAmbientRateExecutor(e,t);case TriggerActionType.SetAmbientLight:return new SetAmbientLightExecutor(e,t);case TriggerActionType.NukeStrike:return new NukeStrikeExecutor(e,t);case TriggerActionType.PlaySoundFxAt:return new PlaySoundFxAtExecutor(e,t);case TriggerActionType.UnrevealAroundWaypoint:return new UnrevealAroundWaypointExecutor(e,t);case TriggerActionType.LightningStrike:return new LightningStrikeExecutor(e,t);case TriggerActionType.TimerText:return new TimerTextExecutor(e,t);case TriggerActionType.CreateCrate:return new CreateCrateExecutor(e,t);case TriggerActionType.IronCurtainAt:return new IronCurtainExecutor(e,t);case TriggerActionType.EvictOccupiers:return new EvictOccupiersExecutor(e,t);case TriggerActionType.Cheer:return new CheerExecutor(e,t);case TriggerActionType.StopSoundsAt:return new StopSoundFxAtExecutor(e,t);default:throw new Error(`Unhandled action type "${TriggerActionType[e.type]}"`)}}}class TriggerCondition{constructor(e,t){this.event=e,this.trigger=t,this.blocking=!1,this.targets=[]}init(e){e=e.getAllPlayers().find(e=>e.country?.name===this.trigger.houseName);e&&(this.player=e)}setTargets(e){this.targets=e}reset(){}getDebugName(){return`${this.event.triggerId}[${this.event.eventIndex}] (${this.trigger.name}).`}}class AmbientLightCondition extends TriggerCondition{constructor(e,t,i){super(e,t),this.type=i,this.threshold=Number(e.params[1])/100}check(e){var t=this.previousAmbient,e=e.mapLightingTrait.getAmbient().ambient;return this.previousAmbient=e,void 0!==t&&t!==e&&("above"===this.type?e>=this.threshold&&t<this.threshold:e<=this.threshold&&t>this.threshold)}}class AnyEventCondition extends TriggerCondition{check(e){return!0}}class AttackedByAnyCondition extends TriggerCondition{check(r,e){return e.filter(e=>{if(e.type!==EventType.ObjectAttacked)return!1;let t=e.target;if(!t.isTechno()||!this.targets.includes(t))return!1;var i=e.attacker?.player;return(!i||!r.alliances.areAllied(i,t.owner)&&i!==t.owner)&&!e.incidental}).map(e=>e.target)}}class AttackedByHouseCondition extends TriggerCondition{constructor(e,t){super(e,t),this.houseId=Number(e.params[1])}check(e,t){return t.filter(e=>{if(e.type!==EventType.ObjectAttacked)return!1;let t=e.target;if(!t.isTechno()||!this.targets.includes(t))return!1;e=e.attacker?.player;return e&&(-1===this.houseId||e?.country?.id===this.houseId)}).map(e=>e.target)}}class BuildingExistsCondition extends TriggerCondition{constructor(e,t,i=!1){super(e,t),this.negate=i,this.objectIndex=Number(e.params[1])}check(){if(!this.player)return!1;for(var e of this.player.buildings)if(e.rules.index===this.objectIndex)return!this.negate;return this.negate}}class BuildObjectTypeCondition extends TriggerCondition{constructor(e,t,i){super(e,t),this.objectType=i,this.objectIndex=Number(e.params[1])}check(e,t){return t.some(e=>e.type===EventType.ObjectSpawn&&e.gameObject.type===this.objectType&&e.gameObject.rules.index===this.objectIndex)}}class ComesNearWaypointCondition extends TriggerCondition{constructor(e,t){super(e,t)}init(e){super.init(e);var t=Number(this.event.params[1]);this.waypointTile=e.map.getTileAtWaypoint(t),this.waypointTile||console.warn(`No valid location found for waypoint ${t}. `+`Skipping event ${this.getDebugName()}.`)}check(t,e){if(!this.waypointTile||!this.player)return!1;for(var i of e)if(i.type===EventType.EnterTile&&i.source.owner===this.player){let e=new RangeHelper(t.map.tileOccupation);if(e.tileDistance(i.target,this.waypointTile)<2)return!0}return!1}}class CreditsBelowCondition extends TriggerCondition{constructor(e,t){super(e,t),this.threshold=Number(e.params[1])}check(e,t){return!!this.player&&this.player.credits<this.threshold}}class CreditsExceedCondition extends TriggerCondition{constructor(e,t){super(e,t),this.threshold=Number(e.params[1])}check(e,t){return!!this.player&&this.player.credits>this.threshold}}class CrossHorizLineCondition extends TriggerCondition{constructor(e,t){super(e,t),this.houseId=Number(this.event.params[1])}check(e,t){return t.filter(t=>t.type===EventType.EnterTile&&t.source.zone!==ZoneType.Air&&this.targets.some(e=>e.ry===t.target.ry)&&(-1===this.houseId||t.source.owner.country?.id===this.houseId)).map(e=>e.target)}}class CrossVertLineCondition extends TriggerCondition{constructor(e,t){super(e,t),this.houseId=Number(this.event.params[1])}check(e,t){return t.filter(t=>t.type===EventType.EnterTile&&t.source.zone!==ZoneType.Air&&this.targets.some(e=>e.rx===t.target.rx)&&(-1===this.houseId||t.source.owner.country?.id===this.houseId)).map(e=>e.target)}}class DestroyedAllBuildingsCondition extends TriggerCondition{constructor(e,t){super(e,t),this.allDestroyed=!1,this.houseId=Number(e.params[1])}check(e,t){return!!this.allDestroyed||!!t.some(e=>{if(e.type!==EventType.ObjectDestroy)return!1;let t=e.target;return!(!t.isBuilding()||t.owner.country?.id!==this.houseId)&&!t.owner.buildings.size})&&(this.allDestroyed=!0)}}class DestroyedAllCondition extends TriggerCondition{constructor(e,t){super(e,t),this.allDestroyed=!1,this.houseId=Number(e.params[1])}check(e,t){return!!this.allDestroyed||!!t.some(e=>{if(e.type!==EventType.ObjectDestroy)return!1;let t=e.target;return!(!t.isTechno()||t.owner.country?.id!==this.houseId)&&!t.owner.getOwnedObjects(!0).length})&&(this.allDestroyed=!0)}}class DestroyedAllUnitsCondition extends TriggerCondition{constructor(e,t){super(e,t),this.allDestroyed=!1,this.houseId=Number(e.params[1])}check(e,t){return!!this.allDestroyed||!!t.some(e=>{if(e.type!==EventType.ObjectDestroy)return!1;let t=e.target;return!(!t.isUnit()||t.owner.country?.id!==this.houseId)&&!this.hasUnitsLeft(t.owner)})&&(this.allDestroyed=!0)}hasUnitsLeft(e){var t;for(t of[ObjectType.Aircraft,ObjectType.Vehicle,ObjectType.Infantry])if(e.getOwnedObjectsByType(t,!0).length)return!0;return!1}}class DestroyedAllUnitsLandCondition extends TriggerCondition{constructor(e,t){super(e,t),this.allDestroyed=!1,this.houseId=Number(e.params[1])}check(e,t){return!!this.allDestroyed||!!t.some(e=>{if(e.type!==EventType.ObjectDestroy)return!1;let t=e.target;return!(!t.isUnit()||t.owner.country?.id!==this.houseId)&&!this.hasLandUnitsLeft(t.owner)})&&(this.allDestroyed=!0)}hasLandUnitsLeft(e){var t;for(t of[ObjectType.Vehicle,ObjectType.Infantry])if(e.getOwnedObjectsByType(t,!0).filter(e=>!e.rules.naval).length)return!0;return!1}}class DestroyedAllUnitsNavalCondition extends TriggerCondition{constructor(e,t){super(e,t),this.allDestroyed=!1,this.houseId=Number(e.params[1])}check(e,t){return!!this.allDestroyed||!!t.some(e=>{if(e.type!==EventType.ObjectDestroy)return!1;let t=e.target;return!(!t.isVehicle()||t.owner.country?.id!==this.houseId)&&!t.owner.getOwnedObjectsByType(ObjectType.Vehicle,!0).filter(e=>e.rules.naval).length})&&(this.allDestroyed=!0)}}class DestroyedBridgeCondition extends TriggerCondition{check(r,e){return e.filter(e=>{if(e.type!==EventType.ObjectDestroy)return!1;let t=e.target;if(!t.isOverlay()||!t.isBridge())return!1;e=t.bridgeTrait?.bridgeSpec;if(!e)return!1;let i=r.map.bridges.findAllBridgeTiles(e);return i.find(e=>this.targets.includes(e))}).map(e=>e.target.tile)}}class DestroyedBuildingsCondition extends TriggerCondition{constructor(e,t){super(e,t),this.count=0,this.threshold=Number(e.params[1])}check(e,t){if(!this.player)return!1;if(this.count>=this.threshold)return!0;for(var i of t)if(i.type===EventType.ObjectDestroy){let e=i.target;e.isBuilding()&&e.owner.country?.id===this.houseId&&this.count++}return this.count>=this.threshold}}class DestroyedByAnyCondition extends TriggerCondition{check(r,e){return e.filter(e=>{if(e.type!==EventType.ObjectDestroy)return!1;let t=e.target;if(!t.isTechno()||!this.targets.includes(t))return!1;var i=e.attackerInfo?.player;return(!i||!r.alliances.areAllied(i,t.owner)&&i!==t.owner)&&!e.incidental}).map(e=>e.target)}}class DestroyedOrCapturedCondition extends TriggerCondition{check(e,t){return t.filter(e=>{if(e.type!==EventType.ObjectDestroy&&e.type!==EventType.ObjectOwnerChange)return!1;let t=e.target;return!(!t.isTechno()||!this.targets.includes(t))}).map(e=>e.target)}}class DestroyedOrCapturedOrInfiltratedCondition extends TriggerCondition{constructor(){super(...arguments),this.eventsFilter=[EventType.ObjectDestroy,EventType.ObjectOwnerChange,EventType.BuildingInfiltration]}check(e,t){return t.filter(e=>{if(!this.eventsFilter.includes(e.type))return!1;let t=e.target;return!(!t.isTechno()||!this.targets.includes(t))}).map(e=>e.target)}}class DestroyedUnitsCondition extends TriggerCondition{constructor(e,t){super(e,t),this.count=0,this.threshold=Number(e.params[1])}check(e,t){if(!this.player)return!1;if(this.count>=this.threshold)return!0;for(var i of t)if(i.type===EventType.ObjectDestroy){let e=i.target;e.isUnit()&&e.owner.country?.id===this.houseId&&this.count++}return this.count>=this.threshold}}class ElapsedScenarioTimeCondition extends TriggerCondition{constructor(e,t){super(e,t),this.timerTicks=Number(this.event.params[1])*GameSpeed.BASE_TICKS_PER_SECOND}check(e){return e.currentTick>this.timerTicks}}class ElapsedTimeCondition extends TriggerCondition{constructor(e,t){super(e,t),this.elapsedTicks=0,this.timerTicks=Number(this.event.params[1])*GameSpeed.BASE_TICKS_PER_SECOND}check(e){return this.elapsedTicks++>this.timerTicks}reset(){this.elapsedTicks=0}}class EnteredByCondition extends TriggerCondition{constructor(e,t){super(e,t),this.houseId=Number(this.event.params[1])}check(e,t){return t.filter(e=>(e.type===EventType.EnterObject||e.type===EventType.EnterTile)&&this.targets.includes(e.target)&&(e.type!==EventType.EnterTile||e.source.zone!==ZoneType.Air)&&(-1===this.houseId||e.source.owner.country?.id===this.houseId)).map(e=>e.target)}}class GlobalVariableCondition extends TriggerCondition{constructor(e,t,i){super(e,t),this.value=i,this.blocking=!0,this.variableIdx=Number(e.params[1])}check(e){return e.triggers.getGlobalVariable(this.variableIdx)===this.value}}class HealthBelowAnyCondition extends TriggerCondition{constructor(e,t,i){super(e,t),this.threshold=i}check(e,t){return t.filter(e=>{if(e.type!==EventType.HealthChange)return!1;let t=e.target;return!(!t.isTechno()||!this.targets.includes(t))&&(e.currentHealth<this.threshold&&e.prevHealth>this.threshold)}).map(e=>e.target)}}class HealthBelowCombatCondition extends TriggerCondition{constructor(e,t,i){super(e,t),this.threshold=i}check(e,t){return t.filter(e=>{if(e.type!==EventType.InflictDamage)return!1;let t=e.target;return!(!t.isTechno()||!this.targets.includes(t))&&(e.currentHealth<this.threshold&&e.prevHealth>this.threshold)}).map(e=>e.target)}}class LocalVariableCondition extends TriggerCondition{constructor(e,t,i){super(e,t),this.value=i,this.blocking=!0,this.variableIdx=Number(e.params[1])}check(e){return e.triggers.getLocalVariable(this.variableIdx)===this.value}}class LowPowerCondition extends TriggerCondition{constructor(e,t){super(e,t),this.houseId=Number(this.event.params[1])}init(e){super.init(e),this.targetPlayer=e.getAllPlayers().find(e=>e.country?.id===this.houseId)}check(){return!!this.targetPlayer?.powerTrait?.isLowPower()}}class NoEventCondition extends TriggerCondition{check(e){return!1}}class NoFactoriesLeftCondition extends TriggerCondition{check(){if(!this.player)return!1;for(var e of this.player.buildings)if(e.factoryTrait)return!1;return!0}}class PickupCrateAnyCondition extends TriggerCondition{check(e,t){return t.some(e=>e.type===EventType.CratePickup)}}class PickupCrateCondition extends TriggerCondition{check(e,t){return t.filter(e=>e.type===EventType.CratePickup&&this.targets.includes(e.source)).map(e=>e.source)}}class RandomDelayCondition extends TriggerCondition{constructor(){super(...arguments),this.elapsedTicks=0}check(e){return this.timerTicks??(this.timerTicks=Math.floor(e.generateRandomInt(50,150)/100*Number(this.event.params[1]))*GameSpeed.BASE_TICKS_PER_SECOND),this.elapsedTicks++>this.timerTicks}reset(){this.timerTicks=void 0,this.elapsedTicks=0}}class SpiedByCondition extends TriggerCondition{constructor(e,t){super(e,t),this.houseId=Number(this.event.params[1])}check(e,t){return t.filter(e=>e.type===EventType.BuildingInfiltration&&this.targets.includes(e.target)&&(-1===this.houseId||e.source.owner.country?.id===this.houseId)).map(e=>e.target)}}class SpyEnteringAsHouseCondition extends TriggerCondition{constructor(e,t){super(e,t),this.houseId=Number(e.params[1])}check(e,t){return t.filter(e=>{if(e.type!==EventType.BuildingInfiltration)return!1;var t=e.target;return!!this.targets.includes(t)&&(-1===this.houseId||e.source.disguiseTrait?.getDisguise()?.owner?.country?.id===this.houseId)}).map(e=>e.target)}}class SpyEnteringAsInfantryCondition extends TriggerCondition{constructor(e,t){super(e,t),this.infantryIdx=Number(e.params[1])}check(e,t){return t.filter(e=>{if(e.type!==EventType.BuildingInfiltration)return!1;var t=e.target;return!!this.targets.includes(t)&&e.source.disguiseTrait?.getDisguise()?.rules.index===this.infantryIdx}).map(e=>e.target)}}class TimerExpiredCondition extends TriggerCondition{check(e,t){return t.some(e=>e.type===EventType.TimerExpire)}}class TriggerConditionFactory{create(e,t){switch(e.type){case TriggerEventType.NoEvent:return new NoEventCondition(e,t);case TriggerEventType.EnteredBy:return new EnteredByCondition(e,t);case TriggerEventType.SpiedBy:return new SpiedByCondition(e,t);case TriggerEventType.AttackedByAny:return new AttackedByAnyCondition(e,t);case TriggerEventType.DestroyedByAny:return new DestroyedByAnyCondition(e,t);case TriggerEventType.AnyEvent:return new AnyEventCondition(e,t);case TriggerEventType.DestroyedAllUnits:return new DestroyedAllUnitsCondition(e,t);case TriggerEventType.DestroyedAllBuildings:return new DestroyedAllBuildingsCondition(e,t);case TriggerEventType.DestroyedAll:return new DestroyedAllCondition(e,t);case TriggerEventType.CreditsExceed:return new CreditsExceedCondition(e,t);case TriggerEventType.ElapsedTime:return new ElapsedTimeCondition(e,t);case TriggerEventType.MissionTimerExpired:return new TimerExpiredCondition(e,t);case TriggerEventType.DestroyedBuildings:return new DestroyedBuildingsCondition(e,t);case TriggerEventType.DestroyedUnits:return new DestroyedUnitsCondition(e,t);case TriggerEventType.NoFactoriesLeft:return new NoFactoriesLeftCondition(e,t);case TriggerEventType.BuildBuilding:return new BuildObjectTypeCondition(e,t,ObjectType.Building);case TriggerEventType.BuildUnit:return new BuildObjectTypeCondition(e,t,ObjectType.Vehicle);case TriggerEventType.BuildInfantry:return new BuildObjectTypeCondition(e,t,ObjectType.Infantry);case TriggerEventType.BuildAircraft:return new BuildObjectTypeCondition(e,t,ObjectType.Aircraft);case TriggerEventType.CrossesHorizontalLine:return new CrossHorizLineCondition(e,t);case TriggerEventType.CrossesVerticalLine:return new CrossVertLineCondition(e,t);case TriggerEventType.GlobalIsSet:return new GlobalVariableCondition(e,t,!0);case TriggerEventType.GlobalIsCleared:return new GlobalVariableCondition(e,t,!1);case TriggerEventType.DestroyedOrCaptured:return new DestroyedOrCapturedCondition(e,t);case TriggerEventType.LowPower:return new LowPowerCondition(e,t);case TriggerEventType.DestroyedBridge:return new DestroyedBridgeCondition(e,t);case TriggerEventType.BuildingExists:return new BuildingExistsCondition(e,t);case TriggerEventType.ComesNearWaypoint:return new ComesNearWaypointCondition(e,t);case TriggerEventType.LocalIsSet:return new LocalVariableCondition(e,t,!0);case TriggerEventType.LocalIsCleared:return new LocalVariableCondition(e,t,!1);case TriggerEventType.FirstDamagedCombat:return new HealthBelowCombatCondition(e,t,100);case TriggerEventType.HalfHealthCombat:return new HealthBelowCombatCondition(e,t,50);case TriggerEventType.QuarterHealthCombat:return new HealthBelowCombatCondition(e,t,25);case TriggerEventType.FirstDamagedAny:return new HealthBelowAnyCondition(e,t,100);case TriggerEventType.HalfHealthAny:return new HealthBelowAnyCondition(e,t,50);case TriggerEventType.QuarterHealthAny:return new HealthBelowAnyCondition(e,t,25);case TriggerEventType.AttackedByHouse:return new AttackedByHouseCondition(e,t);case TriggerEventType.AmbientLightBelow:return new AmbientLightCondition(e,t,"below");case TriggerEventType.AmbientLightAbove:return new AmbientLightCondition(e,t,"above");case TriggerEventType.ElapsedScenarioTime:return new ElapsedScenarioTimeCondition(e,t);case TriggerEventType.DestroyedOrCapturedOrInfiltrated:return new DestroyedOrCapturedOrInfiltratedCondition(e,t);case TriggerEventType.PickupCrate:return new PickupCrateCondition(e,t);case TriggerEventType.PickupCrateAny:return new PickupCrateAnyCondition(e,t);case TriggerEventType.RandomDelay:return new RandomDelayCondition(e,t);case TriggerEventType.CreditsBelow:return new CreditsBelowCondition(e,t);case TriggerEventType.SpyEnteringAsHouse:return new SpyEnteringAsHouseCondition(e,t);case TriggerEventType.SpyEnteringAsInfantry:return new SpyEnteringAsInfantryCondition(e,t);case TriggerEventType.DestroyedAllUnitsNaval:return new DestroyedAllUnitsNavalCondition(e,t);case TriggerEventType.DestroyedAllUnitsLand:return new DestroyedAllUnitsLandCondition(e,t);case TriggerEventType.BuildingNotExists:return new BuildingExistsCondition(e,t,!0);default:throw new Error(`Unhandled trigger event type "${TriggerEventType[e.type]}"`)}}}class TriggerManager{constructor(){this.disposables=new CompositeDisposable,this.triggerInstances=new Map,this.targetsByTag=new Map,this.conditionFactory=new TriggerConditionFactory,this.executorFactory=new TriggerExecutorFactory,this.pendingGameEvents=[],this.globalVariables=new Map,this.localVariables=new Map}init(i){var t,e,r,s,a=i.map.getInitialMapObjects()["technos"];for(let t of a)if(t.tag){let e=this.targetsByTag.get(t.tag);e||(e=[],this.targetsByTag.set(t.tag,e));var n=i.map.tiles.getByMapCoords(t.rx,t.ry);!n||(n=i.map.getObjectsOnTile(n).find(e=>e.name===t.name&&e.type===t.type))&&e.push(n)}for(t of i.map.getCellTags()){var o=i.map.tiles.getByMapCoords(t.coords.x,t.coords.y);if(o){let e=this.targetsByTag.get(t.tagId);e||(e=[],this.targetsByTag.set(t.tagId,e)),e.push(o)}else console.warn(`CellTag out of bounds at (${t.coords.x}, ${t.coords.y}). Skipping.`)}for([e,r]of i.map.getVariables())this.localVariables.set(e,r.clone());for(s of i.map.getTriggers())this.triggerInstances.set(s.id,this.createTriggerInstance(s,i));this.disposables.add(i.events.subscribe(e=>this.pendingGameEvents.push(e)))}createTriggerInstance(i,r){let s=this.targetsByTag.get(i.tag.id)??[];return{trigger:i,conditions:i.events.map(e=>{let t=this.conditionFactory.create(e,i);return t.setTargets(s),t.init(r),t}).sort((e,t)=>Number(t.blocking)-Number(e.blocking)),targets:s,remainingTargets:new Set(i.tag.repeatType===TagRepeatType.OnceAll?s:[]),disabled:i.disabled,finished:!1}}update(i){var r,s=this.pendingGameEvents.splice(0,this.pendingGameEvents.length);for(r of this.triggerInstances.values())if(!r.finished&&!r.disabled){let e=!0,t=[];for(var a of r.conditions){var n=a.check(i,s);if("boolean"==typeof n?n||(e=!1):n.length?t.push(...n):e=!1,a.blocking&&!e)break}if(e){var o=r.trigger;r.conditions.forEach(e=>e.reset?.());let e=[];if(o.tag.repeatType===TagRepeatType.OnceAll){for(var l of t)r.remainingTargets.delete(l);if(r.remainingTargets.size)continue;e=t.length?[t[t.length-1]]:[]}else e=r.targets;this.executeActions(o,e,i),o.tag.repeatType!==TagRepeatType.Repeat&&(r.finished=!0)}}}executeActions(t,i,r){for(var s of t.actions){let e=this.executorFactory.create(s,t);e.execute(r,i)}}setTriggerEnabled(e,t){let i=this.triggerInstances.get(e);i&&(i.disabled=!t)}forceTrigger(e,t){e=this.triggerInstances.get(e);e&&this.executeActions(e.trigger,e.targets,t)}destroyTrigger(e){this.triggerInstances.delete(e)}destroyTag(e){let t=[];for(var[i,r]of this.triggerInstances)r.trigger.tag.id===e&&t.push(i);for(var s of t)this.destroyTrigger(s)}getGlobalVariable(e){return!!this.globalVariables.get(e)?.value}toggleGlobalVariable(e,t){let i=this.globalVariables.get(e);void 0===i?this.globalVariables.set(e,new Variable("No name",t)):i.value=t}getLocalVariable(e){return!!this.localVariables.get(e)?.value}toggleLocalVariable(e,t){let i=this.localVariables.get(e);void 0===i?this.localVariables.set(e,new Variable("No name",t)):i.value=t}dispose(){this.disposables.dispose()}}class TimerExpireEvent{constructor(e){this.target=e,this.type=EventType.TimerExpire}}class CountdownTimer{constructor(){this.ticks=0,this.running=!1}getSeconds(){return Math.floor(this.ticks/GameSpeed.BASE_TICKS_PER_SECOND)}setSeconds(e){this.ticks=Math.max(0,Math.floor(GameSpeed.BASE_TICKS_PER_SECOND*e))}addSeconds(e){this.ticks=Math.max(0,this.ticks+Math.floor(GameSpeed.BASE_TICKS_PER_SECOND*e))}start(){this.running=!0}stop(){this.running=!1}isRunning(){return this.running}update(e){this.running&&(0<this.ticks?this.ticks--:(this.running=!1,e.events.dispatch(new TimerExpireEvent(this))))}}(NotifyObjectTraitAdd=NotifyObjectTraitAdd||{}).onAdd=Symbol(),function(e){e[e.NotStarted=0]="NotStarted",e[e.Started=1]="Started",e[e.Ended=2]="Ended"}(GameStatus=GameStatus||{});class Game{get onEnd(){return this._onEnd.asEvent()}constructor(e,t,i,r,s,a,n,o,l,h,c,u,d,p,g){this.updatableObjects=new Set,this.constructionWorkers=new Map,this.currentTick=0,this.currentTime=0,this.countdownTimer=new CountdownTimer,this._onEnd=new EventDispatcher,this.afterTickCallbacks=[],this.events=new GameEventBus,this.traits=new Traits,this.debugText=new BoxedVar(""),this.world=e,this.map=t,this.rules=i,this.art=r,this.ai=s,this.id=a,this.startTimestamp=n,this.prng=Prng.factory(a,n),this.gameOpts=o,this.gameModeType=l,this.playerList=h,this.unitSelection=c,this.alliances=u,this.desiredSpeed=new BoxedVar(GameSpeed.computeGameSpeed(o.gameSpeed)),this.speed=new BoxedVar(this.desiredSpeed.value),this.nextObjectId=d,this.objectFactory=p,this.botManager=g,this.triggers=new TriggerManager}addPlayer(e){this.playerList.addPlayer(e),this.constructionWorkers.set(e,this.createConstructionWorker(e))}getPlayer(e){return this.playerList.getPlayerAt(e)}getPlayerByName(e){return this.playerList.getPlayerByName(e)}getAiPlayerName(e){let t;return t="number"==typeof e?e:this.gameOpts.aiPlayers.indexOf(e),`@@AI${t+1}@@`}getPlayerNumber(e){return this.playerList.getPlayerNumber(e)}getCombatants(){return this.playerList.getCombatants()}getCivilianPlayer(){return this.playerList.getCivilian()}getAllPlayers(){return this.playerList.getAll()}getNonNeutralPlayers(){return this.playerList.getNonNeutral()}areFriendly(e,t){return e.owner===t.owner||this.alliances.areAllied(e.owner,t.owner)}getWorld(){return this.world}createConstructionWorker(e){return new ConstructionWorker(e,this.rules,this.art,this.map,this)}getConstructionWorker(e){var t=this.constructionWorkers.get(e);if(!t)throw new Error(`No construction worker found for player "${e.name}"`);return t}getUnitSelection(){return this.unitSelection}init(e){this.localPlayer=e,this.createMapObjects(),this.createPlayerInitialUnits(),this.map.terrain.computeAllPassabilityGraphs(),this.mapShroudTrait.init(this),this.crateGeneratorTrait.init(this),this.playerList.getAll().forEach(e=>e.credits=this.gameOpts.credits),this.rules.mpDialogSettings.alliesAllowed&&this.createInitialTeams(),this.botManager.init(this),this.triggers.init(this)}start(){this.status=GameStatus.Started,this.currentTick=0,this.currentTime=0,this.botManager.onGameStart()}createInitialTeams(){for(let t=0;t<this.gameOpts.maxSlots;t++){var i=[...this.gameOpts.humanPlayers,...this.gameOpts.aiPlayers].filter(e=>e?.teamId===t&&e.countryId!==OBS_COUNTRY_ID).map(e=>isHumanPlayerInfo(e)?e.name:this.getAiPlayerName(e));if(1<i.length)for(let t=0;t<i.length-1;t++)for(let e=t+1;e<i.length;e++){var r=this.getPlayerByName(i[t]),s=this.getPlayerByName(i[e]),s=this.alliances.setAlliance(r,s,AllianceStatus.Formed);this.onAllianceChange(s,r,!0)}}}createMapObjects(){var e=this.rules.general.harvesterUnit.every(e=>!isBetween(this.rules.getObject(e,ObjectType.Vehicle).techLevel,0,this.rules.mpDialogSettings.techLevel)),t=this.map.getInitialMapObjects();this.createInitialMapTerrains(t.terrains,e),this.createInitialMapOverlays(t.overlays,e),this.createInitialMapSmudges(t.smudges),this.createInitialMapTechnos(t.technos)}createInitialMapTerrains(e,t){for(var i of e){var r,s,a=i.name;this.validateMapObjectRulesAndArt(a,ObjectType.Terrain)&&((r=this.map.tiles.getByMapCoords(i.rx,i.ry))?(s=this.rules.getObject(a,ObjectType.Terrain),t&&s.spawnsTiberium||(a=this.createObject(ObjectType.Terrain,a),this.spawnObject(a,r))):console.warn(`Invalid map object location (${i.rx},${i.ry})`,i))}}createInitialMapOverlays(e,r){let s=new Map,a=new Map;var n,t,i,o=this.map.bridges.findMapHighBridgeHeadTiles();let l=this.map.bridges.findBridgeSpecsForHeadTiles([...o]);for(n of e){var h=this.rules.getOverlayName(n.id);if(this.validateMapObjectRulesAndArt(h,ObjectType.Overlay)){let e=this.createObject(ObjectType.Overlay,h);e.overlayId=n.id,e.value=n.value;let t=n.rx,i=n.ry;if(e.isBridge()&&e.isHighBridge()){e.position.tileElevation=4;var c=l.find(e=>rectContainsPoint({x:e.start.rx,y:e.start.ry,...this.map.bridges.getBridgeSize(e)},{x:t,y:i}));if(c){var{type:h,isXBridge:u,isHigh:c}=c;if(!c){console.warn(`Expected high bridge but found low bridge overlay at location (${t},${i})`),e.dispose();continue}u!==e.isXBridge()&&(d=BridgeOverlayTypes.calculateHighBridgeOverlayId(h,u),e.overlayId!==d&&(e.overlayId=d,e.name=this.rules.getOverlayName(d)))}t+=e.isXBridge()?0:-1,i+=e.isXBridge()?-1:0}var d,u=this.map.tiles.getByMapCoords(t,i);if(u)if(e.rules.tiberium&&(void 0===(d=OreOverlayTypes.getOverlayTibType(n.id))||void 0!==(d=OreSpread.calculateOverlayId(d,u))&&d!==n.id&&(e.dispose(),e=this.createObject(ObjectType.Overlay,this.rules.getOverlayName(d)),e.overlayId=d,e.value=n.value)),BridgeOverlayTypes.isLowBridge(n.id))BridgeOverlayTypes.isBridgePlaceholder(n.id)||(s.set(u,n.value),1===n.value?a.set(u,e):e.dispose());else{if(e.isTiberium())if(this.map.getObjectsOnTile(u).find(e=>e.isTerrain())){e.dispose();continue}r&&e.isTiberium()?e.dispose():this.spawnObject(e,u)}else console.warn(`Invalid map object location (${t},${i})`,n),e.dispose()}}for([t,i]of a){var p=i.isXBridge(),g=this.map.tiles.getByMapCoords(t.rx+(p?0:-1),t.ry+(p?-1:0)),p=this.map.tiles.getByMapCoords(t.rx+(p?0:1),t.ry+(p?1:0));g&&p&&(0===s.get(g)||2===s.get(p))?(i.value=0,this.spawnObject(i,g)):(i.dispose(),console.warn(`Invalid bridge segment @${t.rx},${t.ry}. Skipping.`))}var m,e=[...a.keys()].filter(e=>this.map.bridges.getPieceAtTile(e)?.headType!==BridgeHeadType.None);let y=[...this.map.bridges.findBridgeSpecsForHeadTiles([...e]),...l];for(m of y)for(var T of this.map.bridges.findBridgePieces(m))T.obj.bridgeTrait.bridgeSpec=m;var f,e=y.map(e=>this.map.bridges.findAllBridgeTiles(e)).flat(),v=BridgeOverlayTypes.bridgePlaceholderIds[0],b=this.rules.getOverlayName(v);for(f of e){let e=this.createObject(ObjectType.Overlay,b);e.overlayId=v,this.spawnObject(e,f)}}createInitialMapSmudges(e){for(var t of e){var i=t.name,r=this.map.tiles.getByMapCoords(t.rx,t.ry);r?(i=this.createObject(ObjectType.Smudge,i),this.spawnObject(i,r)):console.warn(`Invalid map object location (${t.rx},${t.ry})`,t)}}createInitialMapTechnos(e){let t=new Map(this.playerList.getAll().filter(e=>!!e.country).map(e=>[e.country.name,e])),r=this.map.getTags();for(let i of e){var s=i.name;if(this.validateMapObjectRulesAndArt(s,i.type)){var a=this.map.tiles.getByMapCoords(i.rx,i.ry);if(a){var n=t.get(i.owner);if(n){if(n.isNeutral){let t=this.createObject(i.type,s);i.tag&&(t.tag=r.find(e=>e.id===i.tag)),t.healthTrait.health=i.health/256*100;let e=!1;if(!t.healthTrait.health){if(!t.isBuilding()||!t.rules.leaveRubble){t.dispose();continue}e=!0}if(i.isInfantry()||i.isVehicle()||i.isAircraft()){t.direction=(-i.direction/256*360+360)%360,i.isInfantry()&&(t.position.subCell=i.subCell);let e=!1;i.onBridge&&(void 0===a.onBridgeLandType?console.warn(`Cannot place unit "${i.name}" on a bridge because `+`no bridge was found at ${a.rx}, `+a.ry):e=!0),t.onBridge=e,t.zone=getZoneType(e?a.onBridgeLandType:a.landType),e&&(t.position.tileElevation+=this.map.tileOccupation.getBridgeOnTile(a)?.tileElevation??0),i.veterancy&&t.veteranTrait?.setRelativeXP(i.veterancy)}else t.poweredTrait?.setTurnedOn(i.poweredOn);this.changeObjectOwner(t,n),this.spawnObject(t,a),e&&this.destroyObject(t,void 0,!0)}}else console.warn(`Invalid owner "${i.owner}" for map object`,i)}else console.warn(`Invalid map object location (${i.rx},${i.ry})`,i)}}}validateMapObjectRulesAndArt(e,t){return this.rules.hasObject(e,t)?!!this.art.hasObject(e,t)||(console.warn(`Map object '${e}' has no art section. Skipping.`),!1):(console.warn(`Map object '${e}' has no rules section. Skipping.`),!1)}createPlayerInitialUnits(){let e=this.playerList.getCombatants().map(e=>e.country);var i=[...this.rules.infantryRules.values(),...this.rules.vehicleRules.values()].filter(t=>t.allowedToStartInMultiplayer&&!t.naval&&-1!==t.techLevel&&t.techLevel<=this.rules.mpDialogSettings.techLevel&&!this.rules.general.baseUnit.includes(t.name)&&e.some(e=>t.isAvailableTo(e)&&t.hasOwner(e)));for(let l of this.playerList.getCombatants()){var h=this.map.startingLocations[l.startLocation],c=this.map.tiles.getByMapCoords(h.x,h.y);if(!c)throw new Error(`Invalid player starting position (${h.x},${h.y})`);let t=this.rules.general.baseUnit.find(e=>{let t=this.rules.getObject(e,ObjectType.Vehicle);return t.isAvailableTo(l.country)&&t.hasOwner(l.country)});if(!t)throw new Error("No suitable MCV found for player country "+l.country?.name);h=this.rules.getObject(t,ObjectType.Vehicle),h=this.createUnitForPlayer(h,l);this.spawnObject(h,c);let e=StartingUnitsGenerator.generate(this.gameOpts.unitCount,[...this.rules.vehicleRules.keys()],i,l.country);this.gameModeType===GameModeType.Unholy&&e.push(...this.rules.general.baseUnit.filter(e=>e!==t).map(e=>({name:e,type:ObjectType.Vehicle,count:1})));var u,d,p;let r=[],s=!1,a=new CardinalTileFinder(this.map.tiles,this.map.mapBounds,c,4,4,e=>!this.map.getGroundObjectsOnTile(e).find(e=>!(e.isSmudge()||e.isOverlay()&&e.isTiberium()))&&0<this.map.terrain.getPassableSpeed(e,SpeedType.Foot,!1,!1)),n=new Map,o=0;for({name:u,type:d,count:p}of e){let i=p;for(;0<i;){let t;if(s||(t=a.getNextTile(),t?r.push(t):s=!0),s&&r.length){var g=r[o];let e=n.get(g);e||(e=new CardinalTileFinder(this.map.tiles,this.map.mapBounds,g,1,0,e=>!this.map.getGroundObjectsOnTile(e).find(e=>!(e.isSmudge()||e.isOverlay()&&e.isTiberium()))&&0<this.map.terrain.getPassableSpeed(e,SpeedType.Foot,!1,!1)),n.set(g,e)),o=(o+1)%r.length,t=e.getNextTile()}if(t){var m,y=this.rules.getObject(u,d);if(d===ObjectType.Vehicle){g=this.createUnitForPlayer(y,l);this.applyInitialVeteran(g,l),this.spawnObject(g,t),i--}else{if(d!==ObjectType.Infantry)throw new Error("Should not reach this line");for(m of Infantry_Infantry.SUB_CELLS.slice(0,i)){let e=this.createUnitForPlayer(y,l);e.position.subCell=m,this.applyInitialVeteran(e,l),this.spawnObject(e,t),i--}}}else i--}}}}applyInitialVeteran(e,t){e.veteranTrait&&(this.rules.general.veteran.initialVeteran?e.veteranTrait.setVeteranLevel(VeteranLevel.Elite):t.country.hasVeteranUnit(e.type,e.name)&&e.veteranTrait.setVeteranLevel(VeteranLevel.Veteran))}createObject(e,t){return this.objectFactory.create(e,t,this.rules,this.art)}createUnitForPlayer(e,t){if(![ObjectType.Aircraft,ObjectType.Vehicle,ObjectType.Infantry].includes(e.type))throw new Error(`Attempted to create an invalid unit type "${e.type}"`);let i=this.createObject(e.type,e.name);return this.changeObjectOwner(i,t),i.purchaseValue=this.sellTrait.computePurchaseValue(i.rules,t),i}createProjectile(e,t,i,r,s){let a=this.createObject(ObjectType.Projectile,e);return a.fromWeapon=i,a.fromObject=t,a.fromPlayer=t.owner,a.target=r,a.isShrapnel=s,a}createLooseProjectile(e,t,i){var r=this.rules.getWeapon(e),s=r.projectile,a=this.rules.getProjectile(s),e=this.rules.getWarhead(r.warhead),e={minRange:0,projectileRules:a,range:Number.POSITIVE_INFINITY,rules:r,speed:Weapon.computeSpeed(r,a),type:WeaponType.Primary,warhead:new Warhead(e)};let n=this.createObject(ObjectType.Projectile,s);return n.fromWeapon=e,n.fromObject=void 0,n.fromPlayer=t,n.target=i,n}createSuperWeapon(e,t,i=!1){var r=this.rules.getSuperWeapon(e);return new SuperWeapon(e,r,t,i)}createTarget(e,t){return new Target(e,t,this.map.tileOccupation)}isValidTarget(e){if(e){if(!e.isSpawned||e.isCrashing)return!1;if(!(e.rules.legalTarget||e.isBuilding()&&e.rules.hospital))return!1;if(e.isBuilding()&&e.rules.invisibleInGame)return!1}return!0}spawnObject(e,t){if(e.isTechno()&&e.limboData)throw new Error(`Object ${e.name}#${e.id} is in limbo. Use unlimboObject instead or clear limboData first`);this.doSpawnObject(e,t)}unspawnObject(e){e.isTechno()&&e.owner&&e.owner.removeOwnedObject(e),this.doUnspawnObject(e)}limboObject(e,t){e.limboData=t,this.doUnspawnObject(e)}unlimboObject(e,t,i=!1){var r=e.limboData;if(!r)throw new Error(`Object ${e.name}#${e.id} has no limboData attached`);e.limboData=void 0,this.doSpawnObject(e,t);let s=this.getUnitSelection();r.selected&&!i&&s.addToSelection(e),void 0!==r.controlGroup&&s.addUnitsToGroup(r.controlGroup,[e],!1)}doSpawnObject(t,e){var i,r;t.position.tile=e,t.isBuilding()&&(r=t.art.foundationCenter,i=e.rx+r.x,r=e.ry+r.y,t.centerTile=this.map.tiles.getByMapCoords(i,r)??this.map.tiles.getPlaceholderTile(i,r)),this.world.spawnObject(t),(t.cachedTraits.tick.length||t.isProjectile()||t.isDebris()||t.isTechno())&&this.updatableObjects.add(t),t.isTechno()&&this.map.technosByTile.add(t),t.isProjectile()||t.isDebris()||this.map.tileOccupation.occupyTileRange(e,t),t.art.canHideThings&&this.map.tileOcclusion.addOccluder(t),t.onSpawn(this),this.traits.filter(NotifySpawn_NotifySpawn).forEach(e=>{e[NotifySpawn_NotifySpawn.onSpawn](t,this)}),this.events.dispatch(new ObjectSpawnEvent(t))}doUnspawnObject(t){var e=t.tile;t.isProjectile()||t.isDebris()||this.map.tileOccupation.unoccupyTileRange(e,t),t.art.canHideThings&&this.map.tileOcclusion.removeOccluder(t),t.isTechno()&&(this.unitSelection.cleanupUnit(t),this.map.technosByTile.remove(t)),this.world.removeObject(t),this.updatableObjects.delete(t),t.onUnspawn(this),this.traits.filter(NotifyUnspawn_NotifyUnspawn).forEach(e=>{e[NotifyUnspawn_NotifyUnspawn.onUnspawn](t,this)}),this.events.dispatch(new ObjectUnspawnEvent(t))}destroyObject(t,i,e=!1,r=!1){if(t.isDestroyed)throw new Error(`Object with ID "${t.id}" is already destroyed`);if(t.isTechno()){let e=t.mindControllableTrait?.getOriginalOwner()??t.owner;!i||t.isBuilding()&&!e.isCombatant()||(i.player.addUnitsKilled(t.type,1),i.player===e||this.alliances.areAllied(i.player,e)||(i.player.score+=t.rules.points)),e.isNeutral||e.addUnitsLost(t.type,1)}if(t.isDestroyed=!0,t.healthTrait&&(t.healthTrait.health=0),t.onDestroy(this,i,e),this.traits.filter(NotifyDestroy_NotifyDestroy).forEach(e=>{e[NotifyDestroy_NotifyDestroy.onDestroy](t,this,i)}),i?.obj?.traits.filter(NotifyTargetDestroy).forEach(e=>{e[NotifyTargetDestroy.onDestroy](i.obj,t,i.weapon,this)}),this.events.dispatch(new ObjectDestroyEvent(t,i,r)),t.isBuilding()&&t.rules.leaveRubble&&t.deathType!==DeathType.Temporal){t.owner.removeOwnedObject(t),this.unitSelection.cleanupUnit(t);r=this.map.tileOccupation.calculateTilesForGameObject(t.tile,t);this.map.terrain.invalidateTiles(r),t.art.canHideThings&&this.map.tileOcclusion.removeOccluder(t),this.updatableObjects.delete(t),t.onUnspawn(this),this.traits.filter(NotifyUnspawn_NotifyUnspawn).forEach(e=>{e[NotifyUnspawn_NotifyUnspawn.onUnspawn](t,this)}),this.events.dispatch(new ObjectUnspawnEvent(t))}else if(t.isSpawned)this.unspawnObject(t);else if(t.isTechno()&&t.owner){if(!t.limboData)throw new Error(`Object with ID "${t.id}" should be in limbo but has no limboData`);t.owner.removeOwnedObject(t)}t.dispose()}getObjectById(e){return this.world.getObjectById(e)}changeObjectOwner(t,e){const i=t.owner;i&&i.removeOwnedObject(t),e.addOwnedObject(t),i&&i!==e&&(this.traits.filter(NotifyOwnerChange_NotifyOwnerChange).forEach(e=>{e[NotifyOwnerChange_NotifyOwnerChange.onChange](t,i,this)}),t.onOwnerChange(i,this),this.events.dispatch(new ObjectOwnerChangeEvent(t,i)),i===this.localPlayer&&t.owner!==this.localPlayer&&(this.unitSelection.removeFromSelection([t]),this.unitSelection.removeUnitsFromGroup([t])))}addObjectTrait(t,i){t.addTrait(i),this.traits.filter(NotifyObjectTraitAdd).forEach(e=>{e[NotifyObjectTraitAdd.onAdd](t,i,this)})}onAllianceChange(t,e,i){this.events.dispatch(new AllianceChangeEvent(t,i?AllianceEventType.Formed:AllianceEventType.Broken,e)),this.traits.filter(NotifyAllianceChange).forEach(e=>{e[NotifyAllianceChange.onChange](t,i,this)})}update(){if(this.status!==GameStatus.NotStarted){this.botManager.update(this),this.status!==GameStatus.Ended&&(void 0===this.lastGameEndCheck||1e3<=this.currentTime-this.lastGameEndCheck)&&(this.checkGameEndConditions(),this.lastGameEndCheck=this.currentTime);for(var e of[...this.updatableObjects])e.isSpawned&&e.update(this);if(this.playerList.getCombatants().forEach(e=>e.cheerCooldownTicks=Math.max(0,e.cheerCooldownTicks-1)),this.traits.filter(NotifyTick).forEach(e=>{e[NotifyTick.onTick](this)}),this.localPlayer&&!this.localPlayer.isObserver&&!this.localPlayer.defeated){var t=this.unitSelection.getSelectedUnits();if(1===t.length){let i=t[0];if(i.isTechno()&&i.owner!==this.localPlayer){let t=this.mapShroudTrait.getPlayerShroud(this.localPlayer);this.map.tileOccupation.calculateTilesForGameObject(i.tile,i).find(e=>!t.isShrouded(e,i.tileElevation))||(this.unitSelection.deselectAll(),this.unitSelection.cleanupUnit(i))}}}for(var i of this.afterTickCallbacks)i();this.afterTickCallbacks.length=0,this.triggers.update(this),this.countdownTimer.update(this),this.currentTick++,this.currentTime+=1e3/GameSpeed.BASE_TICKS_PER_SECOND}}afterTick(e){this.afterTickCallbacks.push(e)}checkGameEndConditions(){this.updateDefeatedPlayers(this.playerList.getCombatants()),(this.localPlayer?.defeated&&!this.localPlayer.isObserver||!this.alliances.getHostilePlayers().length&&1<this.gameOpts.humanPlayers.length+this.gameOpts.aiPlayers.filter(e=>!!e).length)&&this.end()}end(){this.status!==GameStatus.Ended&&(this.status=GameStatus.Ended,this._onEnd.dispatch(this,void 0))}updateDefeatedPlayers(e){let r=this.stalemateDetectTrait?.isStale()&&0===this.stalemateDetectTrait.getCountdownTicks(),s=this.gameOpts.shortGame;e.forEach(t=>{let i;if(r)i=!0;else{let e;e=s?(e=[...t.getOwnedObjectsByType(ObjectType.Building,!0)].some(e=>!e.rules.insignificant),e||t.getOwnedObjects(!0).some(e=>this.rules.general.baseUnit.includes(e.name))):t.getOwnedObjects(!0).some(e=>!e.rules.insignificant&&!e.limboData?.inTransport),i=!e}var e;i&&(t.defeated=!0,(e=this.alliances.getHostilePlayers().some(e=>!e.first.isAi||!e.second.isAi))&&(t.isObserver=!0),this.removeAllPlayerAssets(t),this.events.dispatch(new PlayerDefeatedEvent(t)),e&&(this.mapShroudTrait.getPlayerShroud(t)?.revealAll(),e=t.radarTrait.isDisabled(),t.radarTrait.setDisabled(!1),e&&this.events.dispatch(new RadarOnOffEvent(t,!0))))})}removeAllPlayerAssets(e){e.getOwnedObjects().forEach(e=>{e.isDestroyed||(e.isBuilding()&&e.rules.returnable&&e.rules.needsEngineer&&!e.garrisonTrait?this.changeObjectOwner(e,this.getCivilianPlayer()):e.isBuilding()&&e.wallTrait||this.destroyObject(e,void 0,!0))}),e.getOwnedObjects(!0).forEach(e=>{e.isDestroyed||(e.limboData?.inTransport||e.isBuilding()&&e.wallTrait?this.changeObjectOwner(e,this.getCivilianPlayer()):this.destroyObject(e,void 0,!0))})}redistributeAllPlayerAssets(e){if(e.isObserver)return!1;if(!(this.rules.mpDialogSettings.mustAlly&&!this.rules.mpDialogSettings.allyChangeAllowed))return!1;let t=this.alliances.getAllies(e).filter(e=>!e.isAi&&!e.defeated);if(0<t.length){var i,r=[...t].sort((e,t)=>t.score-e.score)[0];for(i of e.getOwnedObjects(!0))this.changeObjectOwner(i,r);var s,a=Math.floor(e.credits/t.length),e=e.credits%t.length;for(s of t)s.credits+=a;return t[0].credits+=e,!0}return!1}generateRandomInt(e,t){return this.prng.generateRandomInt(e,t)}generateRandom(){return this.prng.generateRandom()}getHash(){return fnv32a([...new Uint8Array(new Float64Array([this.prng.getLastRandom()]).buffer),this.nextObjectId.value,...this.world.getAllObjects().map(e=>e.getHash()),...this.playerList.getAll().map(e=>e.getHash()),this.alliances.getHash(),...this.traits.getAll().map(e=>e.getHash?.()??0)])}debugGetState(){return{currentTick:this.currentTick,lastRandom:this.prng.getLastRandom(),nextObjectId:this.nextObjectId.value,objects:this.world.getAllObjects().map(e=>e.debugGetState()),players:this.playerList.getAll().map(e=>e.debugGetState()),alliances:this.alliances.debugGetState(),traits:this.traits.getAll().reduce((e,t)=>{var i=t.debugGetState?.();return void 0!==i&&(e[t.constructor.name]=i),e},{})}}dispose(){this.world.getAllObjects().forEach(e=>e.dispose()),this.playerList.getAll().forEach(e=>e.dispose()),this.constructionWorkers.forEach(e=>e.dispose()),this.botManager.dispose(),this.triggers.dispose(),this.map.dispose(),this.traits.dispose()}}const RAD_LEVEL_CAP=1e3,PERCENT_AT_MAX=0;class MapRadiationTrait{get onChange(){return this._onChange.asEvent()}constructor(e){this.map=e,this.radSites=new Map,this.radLevelByTile=new Map,this._onChange=new EventDispatcher}getRadLevel(e){return this.radLevelByTile.get(e)}[NotifyTick.onTick](e){var t;this.radLevelByTile.size&&(t=e.rules.radiation,void 0===this.nextDamage?this.nextDamage=Math.max(0,t.radApplicationDelay-1):this.nextDamage<=0?(this.applyDamage(e),this.nextDamage=Math.max(0,t.radApplicationDelay)):this.nextDamage--,void 0===this.nextDecay?this.nextDecay=Math.max(0,t.radLevelDelay-1):this.nextDecay<=0?(this.applyDecay(Math.ceil(t.radLevelDelay/t.radDurationMultiple)),this.radLevelByTile.size?this.nextDecay=Math.max(0,t.radLevelDelay):this.nextDecay=void 0):this.nextDecay--)}applyDamage(a){let n=a.rules.radiation,o=new Warhead(a.rules.getWarhead(n.radSiteWarhead));this.radLevelByTile.forEach((e,t)=>{var i,r,s=Math.min(n.radLevelMax,e)*n.radLevelFactor;for(i of a.map.getGroundObjectsOnTile(t).filter(e=>e.isUnit()&&!(e.isInfantry()&&e.stance===StanceType.Paradrop&&1<e.tileElevation)))o.canDamage(i,t,i.zone)&&(0<(r=o.computeDamage(s,i,a))&&o.inflictDamage(r,i,void 0,a,!0))})}applyDecay(r){var e=new Set(this.radLevelByTile.keys());this.radLevelByTile.clear(),this.radSites.forEach(({radLevel:e,radius:t},i)=>{e-=r;e<=0?this.radSites.delete(i):(this.radSites.set(i,{radLevel:e,radius:t}),this.setRadLevelAround(i,t,e))}),this._onChange.dispatch(this,e)}createRadSite(e,t,i){(t-=this.radSites.get(e)?.radLevel??0)<=0||(this.radSites.set(e,{radLevel:(this.radSites.get(e)?.radLevel??0)+t,radius:i}),(t=this.setRadLevelAround(e,i,t)).size&&this._onChange.dispatch(this,t))}setRadLevelAround(e,t,i){let r=new RangeHelper(this.map.tileOccupation),s=new RadialTileFinder(this.map.tiles,this.map.mapBounds,e,{width:1,height:1},0,t,e=>!!e,!1);var a;let n=new Set;for(;a=s.getNextTile();){var o=r.tileDistance(e,a);o<=t&&(o=Math.ceil(lerp(i,i*PERCENT_AT_MAX,o/t)),this.radLevelByTile.set(a,Math.min(RAD_LEVEL_CAP,(this.radLevelByTile.get(a)??0)+o)),n.add(a))}return n}getRadSiteLevel(e){return this.radSites.get(e)?.radLevel}}class ActionFactory{constructor(){this.factories=new Map}registerFactory(e,t){this.factories.set(e,t)}create(e){let t=this.factories.get(e);if(!t)throw new Error("No factory registered for action type "+e);return t.create()}}class UnitSelectionLite{constructor(e){this.player=e,this.selectedUnits=new Set}update(e){var t,i=[...e].reverse().find(e=>e.owner!==this.player);i&&(e=[i]),this.selectedUnits.clear();for(t of e)t.rules.selectable&&this.selectedUnits.add(t)}getSelectedUnits(){return[...this.selectedUnits].map(e=>e.isDisposed&&e.replacedBy?e.replacedBy:e).filter(e=>!e.isDestroyed&&!e.isCrashing)}isSelected(e){return this.selectedUnits.has(e)}}class OrderActionContext{constructor(){this.unitSelectionByPlayer=new Map}getOrCreateSelection(e){let t=this.unitSelectionByPlayer.get(e);return t||(t=new UnitSelectionLite(e),this.unitSelectionByPlayer.set(e,t)),t}}!function(e){e[e.NoAction=0]="NoAction",e[e.DropPlayer=1]="DropPlayer",e[e.ObserveGame=2]="ObserveGame",e[e.ResignGame=3]="ResignGame",e[e.DebugCommand=4]="DebugCommand",e[e.PlaceBuilding=5]="PlaceBuilding",e[e.SellObject=6]="SellObject",e[e.ToggleRepair=7]="ToggleRepair",e[e.SelectUnits=8]="SelectUnits",e[e.OrderUnits=9]="OrderUnits",e[e.UpdateQueue=10]="UpdateQueue",e[e.ToggleAlliance=11]="ToggleAlliance",e[e.ActivateSuperWeapon=12]="ActivateSuperWeapon",e[e.PingLocation=13]="PingLocation"}(ActionType=ActionType||{});class Action{constructor(e){this.actionType=e}unserialize(e){}serialize(){return new Uint8Array}print(){return""}}class NoAction extends Action{constructor(){super(ActionType.NoAction)}process(){}}class NoActionFactory{create(){return new NoAction}}class BuildingPlaceEvent{constructor(e){this.target=e,this.type=EventType.BuildingPlace}}class BuildingFailedPlaceEvent{constructor(e,t,i){this.name=e,this.player=t,this.tile=i,this.type=EventType.BuildingFailedPlace}}(NotifyPlaceBuilding=NotifyPlaceBuilding||{}).onPlace=Symbol();class PlaceBuildingAction extends Action{constructor(e){super(ActionType.PlaceBuilding),this.game=e}unserialize(e){let t=new DataStream(e);this.buildingRules=this.game.rules.getTechnoByInternalId(t.readUint32(),ObjectType.Building),this.tile={x:t.readUint16(),y:t.readUint16()}}serialize(){let e=new DataStream(8);return e.writeUint32(this.buildingRules.index),e.writeUint16(this.tile.x),e.writeUint16(this.tile.y),e.toUint8Array()}print(){return`Place building ${this.buildingRules.name} at tile (${this.tile.x}, ${this.tile.y})`}process(){var e=this.game.map.tiles.getByMapCoords(this.tile.x,this.tile.y);if(e){var t=this.player;const i=this.tryPlaceBuilding(t,e);i?(this.game.traits.filter(NotifyPlaceBuilding).forEach(e=>{e[NotifyPlaceBuilding.onPlace](i,this.game)}),this.game.events.dispatch(new BuildingPlaceEvent(i))):this.game.events.dispatch(new BuildingFailedPlaceEvent(this.buildingRules.name,t,e))}else console.warn(`Tile ${this.tile.x},${this.tile.y} doesn't exist`)}tryPlaceBuilding(r,s){var a=this.buildingRules;if(r.production){let i=r.production.getQueueForObject(a);if(i.status===QueueStatus.Ready&&i.getFirst().rules===a){let t=this.game.getConstructionWorker(r);if(r.production.isAvailableForProduction(a)&&t.canPlaceAt(a.name,s,{normalizedTile:!0})){s=t.placeAt(a.name,s,!0);r.addUnitsBuilt(a,1),i.shift(a,1);let e=r.production.getPrimaryFactory(FactoryType.BuildingType);return e&&(e.factoryTrait.status=FactoryStatus.Delivering),s[0]}}}}}class PlaceBuildingActionFactory{constructor(e){this.game=e}create(){return new PlaceBuildingAction(this.game)}}class SellObjectAction extends Action{constructor(e){super(ActionType.SellObject),this.game=e}unserialize(e){this.objectId=new DataStream(e).readUint32()}serialize(){return new DataStream(4).writeUint32(this.objectId).toUint8Array()}print(){return"Sell object "+this.objectId}process(){var t=this.player;if(this.game.getWorld().hasObjectId(this.objectId)){let e=this.game.getObjectById(this.objectId);e.isTechno()&&t===e.owner&&e.isSpawned&&(e.isBuilding()?e.buildStatus===BuildStatus.Ready&&!e.warpedOutTrait.isActive():e.traits.find(DockableTrait)?.dock?.rules.unitSell)&&this.game.sellTrait.sell(e)}}}class SellObjectActionFactory{constructor(e){this.game=e}create(){return new SellObjectAction(this.game)}}const orderPriorities=[OrderType.Occupy,OrderType.Dock,OrderType.Attack,OrderType.Capture,OrderType.Repair,OrderType.EnterTransport,OrderType.PlaceBomb,OrderType.Deploy,OrderType.Gather];!function(e){e[e.Default=0]="Default",e[e.Mini=1]="Mini",e[e.Scroll=2]="Scroll",e[e.NoScroll=10]="NoScroll",e[e.Select=18]="Select",e[e.Move=31]="Move",e[e.NoMove=41]="NoMove",e[e.MoveMini=42]="MoveMini",e[e.NoActionMini=52]="NoActionMini",e[e.AttackRange=53]="AttackRange",e[e.AttackNoRange=58]="AttackNoRange",e[e.AttackMini=63]="AttackMini",e[e.Guard=68]="Guard",e[e.GuardMini=73]="GuardMini",e[e.Unknown1=78]="Unknown1",e[e.Unknown2=88]="Unknown2",e[e.Occupy=89]="Occupy",e[e.NoOccupy=99]="NoOccupy",e[e.OccupyMini=100]="OccupyMini",e[e.Deploy=110]="Deploy",e[e.NoDeploy=119]="NoDeploy",e[e.Unknown3=120]="Unknown3",e[e.Sell=129]="Sell",e[e.SellMini=139]="SellMini",e[e.NoSell=149]="NoSell",e[e.RepairMove=150]="RepairMove",e[e.SideRepair=170]="SideRepair",e[e.NoRepair=190]="NoRepair",e[e.Unknown4=191]="Unknown4",e[e.Unknown5=199]="Unknown5",e[e.Dynamite=204]="Dynamite",e[e.Unknown6=209]="Unknown6",e[e.Unknown7=214]="Unknown7",e[e.Unknown8=219]="Unknown8",e[e.Unknown9=224]="Unknown9",e[e.Unknown10=229]="Unknown10",e[e.Unknown11=234]="Unknown11",e[e.Unknwon12=239]="Unknwon12",e[e.Unknown13=249]="Unknown13",e[e.Para=259]="Para",e[e.Unknown14=269]="Unknown14",e[e.Storm=279]="Storm",e[e.EngineerDamage=299]="EngineerDamage",e[e.C4=309]="C4",e[e.Nuke=319]="Nuke",e[e.Unknown16=329]="Unknown16",e[e.Power=339]="Power",e[e.Unknown17=345]="Unknown17",e[e.Iron=346]="Iron",e[e.Unknown18=351]="Unknown18",e[e.Unknown19=356]="Unknown19",e[e.Chrono=357]="Chrono",e[e.DefuseBomb=369]="DefuseBomb",e[e.NoAction=384]="NoAction",e[e.Pan=385]="Pan",e[e.Unknown21=394]="Unknown21",e[e.AttackMove=404]="AttackMove",e[e.Unknown23=413]="Unknown23",e[e.Unknown24=422]="Unknown24",e[e.Unknown25=431]="Unknown25",e[e.Unknown26=432]="Unknown26",e[e.Unknown27=433]="Unknown27",e[e.Unknown28=434]="Unknown28",e[e.Beacon=435]="Beacon",e[e.ForceField=450]="ForceField",e[e.NoForceField=460]="NoForceField",e[e.Mutate=470]="Mutate",e[e.AirStrike=480]="AirStrike",e[e.Dominate=488]="Dominate",e[e.PsychicReveal=496]="PsychicReveal",e[e.SpyPlane=504]="SpyPlane",e[e.SpyPlaneMini=512]="SpyPlaneMini",e[e.NukeMini=513]="NukeMini",e[e.StormMini=514]="StormMini",e[e.PsychicRevealMini=515]="PsychicRevealMini",e[e.DominateMini=516]="DominateMini"}(PointerType=PointerType||{}),function(e){e[e.None=0]="None",e[e.Move=1]="Move",e[e.Attack=2]="Attack",e[e.Enter=3]="Enter",e[e.Capture=4]="Capture",e[e.SpecialAttack=5]="SpecialAttack"}(OrderFeedbackType=OrderFeedbackType||{});class Order{constructor(e){this.orderType=e,this.targetOptional=!0,this.minimapAllowed=!0,this.singleSelectionRequired=!1,this.terminal=!1,this.feedbackType=OrderFeedbackType.None}getPointerType(e,t){return e?PointerType.Mini:PointerType.Default}set(e,t){return this.sourceObject=e,this.target=t,this}isValid(){return!0}isAllowed(){return!0}onAdd(e,t){return!0}}class ObjectMorphEvent{constructor(e,t){this.from=e,this.to=t,this.type=EventType.ObjectMorph}}class MorphIntoTask extends Task{constructor(e){super(),this.game=e}onStart(e){if(!this.morphInto)throw new Error("morphInto not set");e.isBuilding()&&e.buildStatus!==BuildStatus.BuildDown&&this.morphInto.type!==ObjectType.Building&&this.children.push(new PackBuildingTask(this.game)),e.isVehicle()&&this.morphInto.type===ObjectType.Building&&this.children.push(new TurnTask(180))}onTick(t){if(!this.morphInto)throw new Error("morphInto not set");let e=this.game.getUnitSelection();var i=e.isSelected(t),r=e.getOrCreateSelectionModel(t).getControlGroupNumber(),s=this.morphInto;let a;if(s.type===ObjectType.Building){if(t.isVehicle()&&t.parasiteableTrait?.isInfested()&&!t.parasiteableTrait.beingBoarded)return!0;var n=t.tile;let e=this.game.getConstructionWorker(t.owner);if(!e.canPlaceAt(this.morphInto.name,n,{ignoreAdjacent:!0,ignoreObjects:[t]}))return!0;this.game.unspawnObject(t),t.dispose(),[a]=e.placeAt(this.morphInto.name,n),a.healthTrait.health=t.healthTrait.health}else{let e=t.unitOrderTrait.getTasks().filter(e=>e instanceof MoveTask);this.game.unspawnObject(t),t.dispose(),a=this.game.createUnitForPlayer(this.morphInto,t.owner),a.direction=180,a.healthTrait.health=t.healthTrait.health;n=t.art.foundationCenter;this.game.spawnObject(a,this.game.map.tiles.getByMapCoords(t.tile.rx+n.x,t.tile.ry+n.y)),e.forEach(e=>a.unitOrderTrait.addTask(e))}return a.purchaseValue=t.purchaseValue,t.replacedBy=a,i&&e.addToSelection(a),void 0!==r&&e.addUnitsToGroup(r,[a],!1),this.game.events.dispatch(new ObjectMorphEvent(t,a)),!0}}class UndeployIntoTask extends MorphIntoTask{onStart(e){var t=e.rules.undeploysInto;if(!t)throw new Error(`Object type "${e.name}" doesn't undeploy into anything`);this.morphInto=this.game.rules.getObject(t,ObjectType.Vehicle),super.onStart(e)}}class RallyPointChangeEvent{constructor(e){this.target=e,this.type=EventType.RallyPointChange}}class MoveToBlockTask extends Task{constructor(e,t){super(),this.game=e,this.target=t,this.preventOpportunityFire=!1,this.useChildTargetLines=!0,this.attackPerformed=!1}onStart(e){this.children.push(new MoveTask(this.game,this.target.centerTile,!1,{closeEnoughTiles:1,pathFinderIgnoredBlockers:[this.target],stopOnBlocker:this.target}))}onTick(e){if(this.attackPerformed||this.isCancelling()||!e.attackTrait||e.attackTrait.isDisabled())return!0;if(e.moveTrait.lastMoveResult!==MoveResult.CloseEnough)return!0;var t=e.attackTrait.selectWeaponVersus(e,this.target,this.game,!0);return!t||(this.children.push(e.attackTrait.createAttackTask(this.game,this.target,this.target.tile,t,{force:!0})),!(this.attackPerformed=!0))}}const TARGET_UPDATE_TILES=10;class MoveTargetTask extends MoveTask{constructor(e,t){super(e,t.tile,t.onBridge,{forceMove:!0,pathFinderIgnoredBlockers:[t]}),this.target=t,this.tilesSinceTargetUpdate=0}onTick(t){if(!(this.isCancelling()||t.moveTrait.moveState!==MoveState.ReachedNextWaypoint||this.target.tile===this.targetTile&&this.target.onBridge===this.toBridge&&this.target.moveTrait.isIdle())){let e=!1;var i;(t.tile===this.targetTile&&this.target.tile!==this.targetTile||this.tilesSinceTargetUpdate++>TARGET_UPDATE_TILES)&&(e=!0),e&&(this.tilesSinceTargetUpdate=0,(i=this.target.moveTrait.currentWaypoint)?this.updateTarget(i.tile,!!i.onBridge):this.updateTarget(this.target.tile,this.target.onBridge))}return super.onTick(t)}forceCancel(e){return super.forceCancel(e)}getTargetLinesConfig(e){return{target:this.target,pathNodes:[]}}}class MoveOrder extends Order{constructor(e,t,i,r=!1){super(r?OrderType.ForceMove:OrderType.Move),this.game=e,this.map=t,this.unitSelection=i,this.forceMove=r,this.targetOptional=!1,this.feedbackType=OrderFeedbackType.Move}getPointerType(e){let t=this.isAllowed();var i,r,s,a,n;return!t||this.forceMove||this.sourceObject.isBuilding()||this.game.mapShroudTrait.getPlayerShroud(this.sourceObject.owner)?.isShrouded(this.target.tile,this.target.obj?.tileElevation)||(i=!!this.target.getBridge(),r=this.sourceObject.rules.speedType,s=this.sourceObject.isInfantry(),a=this.sourceObject.rules.movementZone===MovementZone.Fly,n=this.map.getObjectsOnTile(this.target.tile).some(e=>(e.isInfantry()||e.isVehicle())&&e.disguiseTrait?.hasTerrainDisguise()),t=a?this.sourceObject.rules.airportBound||this.target.tile.landType===LandType.Cliff||0<this.map.terrain.getPassableSpeed(this.target.tile,SpeedType.Amphibious,!1,i)&&!n:0<this.map.terrain.getPassableSpeed(this.target.tile,r,s,i)&&!n&&!(this.target.obj?.isTechno()&&!this.game.areFriendly(this.target.obj,this.sourceObject))),e?t?PointerType.MoveMini:PointerType.NoActionMini:t?PointerType.Move:PointerType.NoMove}isValid(){return!(this.sourceObject.isBuilding()&&(!this.sourceObject.rules.undeploysInto||this.sourceObject.rules.constructionYard&&!this.game.gameOpts.mcvRepacks)&&!this.sourceObject.rallyTrait?.getRallyPoint())&&(this.forceMove||!this.target.obj||(this.target.obj.isOverlay()||this.target.obj.isBuilding())&&this.target.obj.rules.wall||this.target.obj.isTechno()&&this.target.obj.owner===this.sourceObject.owner&&this.unitSelection.isSelected(this.target.obj)||(this.target.obj.isInfantry()||this.target.obj.isVehicle())&&!!this.target.obj.disguiseTrait?.hasTerrainDisguise()||this.target.obj.isTechno()&&!this.game.areFriendly(this.target.obj,this.sourceObject))}isAllowed(){return(!this.sourceObject.isUnit()||!this.sourceObject.moveTrait.isDisabled())&&(this.game.mapShroudTrait.getPlayerShroud(this.sourceObject.owner)?.isShrouded(this.target.tile,this.target.obj?.tileElevation)?this.sourceObject.rules.moveToShroud:!(!this.forceMove&&this.target.obj?.isTechno()&&this.target.obj.owner===this.sourceObject.owner&&this.unitSelection.isSelected(this.target.obj)))}process(){const e=this.sourceObject;if(!e.isBuilding()||!e.rallyTrait?.getRallyPoint()){var t=this.game.rules.general.closeEnough;return e.isBuilding()&&e.rules.undeploysInto?[new UndeployIntoTask(this.game),new MoveTask(this.game,this.target.tile,!!this.target.getBridge(),{closeEnoughTiles:t,forceMove:this.forceMove})]:e.isUnit()?this.isEnemyBuildingBlock()?[new MoveToBlockTask(this.game,this.target.obj)]:this.isFollowMove()?[new MoveTargetTask(this.game,this.target.obj)]:[new MoveTask(this.game,this.target.tile,!!this.target.getBridge(),{closeEnoughTiles:t,forceMove:this.forceMove})]:void 0}}isEnemyBuildingBlock(){return this.forceMove&&this.sourceObject.isVehicle()&&!this.sourceObject.rules.consideredAircraft&&this.target.obj?.isBuilding()&&!this.game.areFriendly(this.sourceObject,this.target.obj)}isFollowMove(){return this.forceMove&&this.target.obj?.isInfantry()&&this.sourceObject.isVehicle()&&!this.sourceObject.rules.consideredAircraft&&!this.target.obj.moveTrait.isIdle()}onAdd(t,e){var i=this.sourceObject.isBuilding()&&this.sourceObject.rules.undeploysInto;if(i&&this.sourceObject.buildStatus===BuildStatus.BuildUp)return this.sourceObject.unitOrderTrait.getTasks().find(e=>e instanceof WaitForBuildUpTask)?.setCancellable(!0),!0;if(!i&&this.sourceObject.isBuilding()&&this.sourceObject.rallyTrait?.getRallyPoint())return this.sourceObject.rallyTrait.changeRallyPoint(this.target.tile,this.sourceObject,this.game),this.game.events.dispatch(new RallyPointChangeEvent(this.sourceObject)),!1;if(!this.isEnemyBuildingBlock()&&!this.isFollowMove()&&!e&&this.isValid()&&this.isAllowed()){this.sourceObject.attackTrait?.cancelOpportunityFire();let e=t.find(e=>e.constructor===MoveTask&&!e.isCancelling());if(e)return e.setForceMove(this.forceMove),e.updateTarget(this.target.tile,!!this.target.getBridge(),!0),e.children.length&&e.children[0]instanceof AttackTask&&e.children[0].cancel(),t.splice(t.indexOf(e)+1),this.sourceObject.unitOrderTrait.clearOrders(),!1;if(this.sourceObject.isUnit()&&this.sourceObject.rules.movementZone===MovementZone.Fly){let e=t.find(e=>[AttackTask,AttackMoveTask,AttackMoveTargetTask].includes(e.constructor)&&!e.isCancelling());e&&e.forceCancel(this.sourceObject)&&t.splice(t.indexOf(e))}}return!0}}class DeployIntoTask extends MorphIntoTask{onStart(e){var t=e.rules.deploysInto;if(!t)throw new Error(`Object type "${e.name}" doesn't deploy into anything`);this.morphInto=this.game.rules.getObject(t,ObjectType.Building),super.onStart(e)}onTick(e){return!!this.isCancelling()||super.onTick(e)}}class UnitDeployUndeployEvent{constructor(e,t){this.unit=e,this.deployType=t,this.type=EventType.UnitDeployUndeploy}}class PrimaryFactoryChangeEvent{constructor(e){this.target=e,this.type=EventType.PrimaryFactoryChange}}!function(e){e[e.None=0]="None",e[e.OnlyPassengers=1]="OnlyPassengers",e[e.All=2]="All"}(EvacState=EvacState||{});const MAX_EVAC_TRIES=3;class EvacuateTransportTask extends Task{constructor(e,t){super(),this.game=e,this.soft=t,this.evacState=EvacState.None,this.evacTries=0,this.turnPerformed=!1,this.preventLanding=!1}forceEvac(){this.evacState=EvacState.All}onStart(e){if(!e.transportTrait)throw new Error(`Object "${e.name}" is not a valid transport`);var t=e.transportTrait;0<t.units.length&&(this.evacState=this.evacState!==EvacState.OnlyPassengers&&1!==t.units.length||!e.rules.gunner?EvacState.OnlyPassengers:EvacState.All)}onTick(e){if(this.isCancelling()||this.evacState===EvacState.None)return!0;if(e.zone===ZoneType.Air)return this.children.push(new CallbackTask(()=>e.zone!==ZoneType.Air)),!1;let t=e.transportTrait.units;if(!t.length||e.rules.gunner&&1===t.length&&this.evacState!==EvacState.All)return!0;var i=t[t.length-1],r=this.findValidEvacTarget(e,i);if(r&&!this.turnPerformed){this.turnPerformed=!0;var s=(r.dir+180)%360;if(e.direction!==s)return this.children.push(new TurnTask(s)),!1}return this.evacuateUnit(i,e,r)?(t.pop(),this.children.push(new WaitMinutesTask(1/60)),!1):!(++this.evacTries<=MAX_EVAC_TRIES)||(this.children.push(new WaitMinutesTask(.05)),!1)}evacuateUnit(e,t,i){if(!i)return!this.soft&&(e.position.tile=t.tile,e.position.tileElevation=t.tileElevation,e.onBridge=t.onBridge,e.zone=t.zone,this.game.destroyObject(e,{player:e.owner}),!0);var{spawnNode:r,moveNode:i}=i;return e.position.tileElevation=r.onBridge?.tileElevation??0,e.onBridge=!!r.onBridge,e.zone=this.game.map.getTileZone(r.tile,!r.onBridge),this.game.unlimboObject(e,r.tile),e.unitOrderTrait.unmarkNextQueuedOrder(),i?e.unitOrderTrait.addTask(new MoveTask(this.game,i.tile,!!i.onBridge)):e.unitOrderTrait.addTask(new ScatterTask(this.game)),this.game.events.dispatch(new LeaveTransportEvent(t)),!0}findValidEvacTarget(a,n){let o=this.game.map,l=new MovePositionHelper(o);var h,c,u,d,p,t=a.onBridge?o.tileOccupation.getBridgeOnTile(a.tile):void 0,i=(a.direction+180)%360;let g;for(let e=0;e<=180;e+=45)for(h of e&&e<180?[i+e,i-e]:[i+e]){var m=FacingUtil.toMapCoords(h);let i=a.tile,r=t,s;for(let t=1;t<=2;t++){if(2===t){if(!s)break;i=s.tile,r=s.onBridge}var y,T=a.tile.rx+Math.sign(m.x)*t,f=a.tile.ry+Math.sign(m.y)*t,v=o.tiles.getByMapCoords(T,f);if(!v||!o.mapBounds.isWithinBounds(v))break;let e=[o.tileOccupation.getBridgeOnTile(v)];e[0]&&e.push(void 0);for(y of e)if(c=v,u=y,d=r,p=i,0<o.terrain.getPassableSpeed(c,n.rules.speedType,n.isInfantry(),!!u)&&l.isEligibleTile(c,u,d,p)&&!o.terrain.findObstacles({tile:c,onBridge:u},n).length){if(1!==t)return{spawnNode:s,moveNode:{tile:v,onBridge:y},dir:h};s={tile:v,onBridge:y},g={spawnNode:s,moveNode:void 0,dir:h}}}}if(g)return g}}class DeployOrder extends Order{constructor(e,t){super(t?OrderType.Deploy:OrderType.DeploySelected),this.game=e,this.targeted=t,this.minimapAllowed=!1,this.getPointerType=()=>this.isAllowed()?PointerType.Deploy:PointerType.NoDeploy,this.targetOptional=!t,this.singleSelectionRequired=t}isValid(){if(this.targeted&&(!this.target.obj||this.target.obj!==this.sourceObject))return!1;let e=this.sourceObject;return!!(e.isInfantry()&&e.deployerTrait&&![StanceType.Cheer].includes(e.stance)||e.isVehicle()&&e.deployerTrait||e.isVehicle()&&e.rules.deploysInto||e.isVehicle()&&e.transportTrait||e.isBuilding()&&e.rules.factory&&!e.owner.production?.isPrimaryFactory(e)||e.isBuilding()&&e.garrisonTrait?.units.length)}isAllowed(){let t=this.sourceObject;if(t.isVehicle()&&t.transportTrait)return!!(t.transportTrait.units.length&&0<this.game.map.terrain.getPassableSpeed(t.tile,SpeedType.Foot,!1,t.onBridge));if((t.isInfantry()||t.isVehicle())&&t.deployerTrait)return!0;if(t.isVehicle()&&t.rules.deploysInto){if(t.parasiteableTrait?.isInfested()&&!t.parasiteableTrait.beingBoarded)return!1;let e=this.game.getConstructionWorker(t.owner);if(t.moveTrait.currentWaypoint?.onBridge)return!1;var i=t.moveTrait.currentWaypoint?.tile??t.tile;return e.canPlaceAt(t.rules.deploysInto,i,{ignoreObjects:[t],ignoreAdjacent:!0})}if(t.isBuilding()&&t.rules.factory)return!0;if(t.isBuilding()&&t.garrisonTrait?.units.length)return!0;throw new Error("Shouldn't reach this point. Missed a case.")}process(){const e=this.sourceObject;return e.isVehicle()&&e.transportTrait?[new EvacuateTransportTask(this.game,!0)]:e.isBuilding()&&e.rules.factory?void 0:e.isVehicle()&&e.rules.deploysInto?[new DeployIntoTask(this.game)]:(e.isInfantry()||e.isVehicle())&&e.deployerTrait?[new CallbackTask(()=>{e.deployerTrait.toggleDeployed(),this.game.events.dispatch(new UnitDeployUndeployEvent(e,e.deployerTrait.isDeployed()?"undeploy":"deploy"))})]:e.isBuilding()&&e.garrisonTrait?.units.length?[new CallbackTask(()=>{e.garrisonTrait.evacuate(this.game,!0)})]:void 0}onAdd(t,e){let i=this.sourceObject;if(i.isBuilding()&&i.rules.factory)return i.owner.production.setPrimaryFactory(i),this.game.events.dispatch(new PrimaryFactoryChangeEvent(i)),!1;if(i.isVehicle()&&i.transportTrait&&!e&&this.isValid()&&this.isAllowed()){let e=t.find(e=>e.constructor===EvacuateTransportTask&&!e.isCancelling());if(e)return e.forceEvac(),!1}return!0}}class CheerEvent{constructor(e){this.player=e,this.type=EventType.Cheer}}class DeployNotAllowedEvent{constructor(e){this.target=e,this.type=EventType.DeployNotAllowed}}const ORDER_UNIT_LIMIT=128;class OrderUnitsAction extends Action{constructor(e,t,i,r){super(ActionType.OrderUnits),this.game=e,this.map=t,this.orderActionContext=i,this.orderFactory=r,this.queue=!1,this.isInvalid=!1}unserialize(t){let i=new DataStream(t);this.orderType=i.readUint8();var r=i.readUint8();if(0!==r){var s=i.readUint16(),t=i.readUint16();this.queue=2<r&&Boolean(i.readUint8());let e;if(3<r){r=i.readUint32();if(!this.game.getWorld().hasObjectId(r))return void(this.isInvalid=!0);e=this.game.getObjectById(r)}else e=void 0;t=this.map.tiles.getByMapCoords(s,t);t?this.target=this.game.createTarget(e,t):this.isInvalid=!0}}serialize(){let e=new DataStream(11);e.dynamicSize=!1,e.writeUint8(this.orderType);let t=0;e.writeUint8(t),this.target&&(e.writeUint16(this.target.tile.rx),e.writeUint16(this.target.tile.ry),t+=2,i=(this.target.obj||this.target.getBridge())?.id,!this.queue&&void 0===i||(e.writeUint8(Number(this.queue)),t+=1),void 0!==i&&(e.writeUint32(i),t+=1));var i=e.position;return 0<t&&(e.seek(1),e.writeUint8(t)),new Uint8Array(e.buffer,e.byteOffset,i)}print(){return this.isInvalid?"":OrderType[this.orderType]+" order "+(this.target?`[obj: ${(this.target.obj||this.target.getBridge())?.name||"<none>"}, `+`tile: ${this.target.tile.rx},${this.target.tile.ry}]`+(this.queue?"(queue)":""):"")}process(){if(!this.isInvalid){let n=this.player;const c=this.game.mapShroudTrait.getPlayerShroud(n);if(c){const u=this.target?.obj;if(u){let e=this.game.map.tileOccupation.calculateTilesForGameObject(u.tile,u);if(!e.find(e=>!c.isShrouded(e,u.tileElevation)))return}let e=this.validateOrders(n).slice(0,ORDER_UNIT_LIMIT),a=[],t=[],r=[],i=[],s=[];if(e.forEach(e=>{(e instanceof MoveOrder?t:e.orderType===OrderType.Scatter?r:e.orderType===OrderType.DeploySelected?i:e.orderType===OrderType.Cheer?s:a).push(e)}),t.length&&this.target){var o=t[0].isEnemyBuildingBlock(),l=t[0].isFollowMove();if(o||l)t.forEach(e=>a.push(e));else{let r=this.target.getBridge();var h=t[0].forceMove,l=t.map(e=>e.sourceObject);let s=new MovePositionHelper(this.map).findPositions(l,this.target.tile,r,h);t.forEach(e=>{var t=s.get(e.sourceObject),i=!r||r.isHighBridge()?this.map.tileOccupation.getBridgeOnTile(t):r,t=this.game.createTarget(i,t);e.target=t,a.push(e)})}}if(r.length){h=r.map(e=>e.sourceObject).filter(e=>e.isInfantry()||e.isVehicle());let i=new ScatterPositionHelper(this.game).findPositions(h);r.forEach(e=>{var t=i.get(e.sourceObject);t&&(t=this.game.createTarget(t.onBridge,t.tile),e.target=t,a.push(e))})}if(i.length){let t=[];i.forEach(e=>{((e.sourceObject.isInfantry()||e.sourceObject.isVehicle())&&e.sourceObject.deployerTrait?t:a).push(e)});let e=t.filter(e=>!e.sourceObject.deployerTrait.isDeployed());e.length?e.forEach(e=>a.push(e)):t.forEach(e=>a.push(e))}s.length&&(n.cheerCooldownTicks||(n.cheerCooldownTicks=this.game.rules.general.maximumCheerRate,a.push(...s),this.game.events.dispatch(new CheerEvent(n)))),a.forEach(e=>e.sourceObject.unitOrderTrait.addOrder(e,this.queue)),this.updateWaypointPaths(a)}}}validateOrders(e){let i=this.orderActionContext.getOrCreateSelection(e);var r,s=i.getSelectedUnits();let t=this.orderFactory.create(this.orderType,i);t.target=this.target;let a=[];for(r of s)if(!(r.owner!==e||r.rules.spawned||r.isDestroyed||r.isCrashing||r.isDisposed||r.warpedOutTrait.isActive()||(t.sourceObject=r,t instanceof DeployOrder&&t.isValid()&&!t.isAllowed()&&this.game.events.dispatch(new DeployNotAllowedEvent(r)),t.singleSelectionRequired&&1<s.length)))if(t.isValid()&&t.isAllowed()){let e=this.orderFactory.create(this.orderType,i);e.set(r,this.target),a.push(e)}else{let t=!1;for(var n of orderPriorities){let e=this.orderFactory.create(n,i);if(e.set(r,this.target),!(e.singleSelectionRequired&&1<s.length)&&(e.targetOptional===!this.target&&e.isValid()&&e.isAllowed())){a.push(e),t=!0;break}}if(!t&&this.target&&this.orderType!==OrderType.Deploy){let e=this.orderFactory.create(OrderType.Move,i);e.set(r,this.target),e.isValid()&&e.isAllowed()&&a.push(e)}}return a}updateWaypointPaths(i){if(this.queue&&this.target){let e=i.map(e=>e.sourceObject);var t=[...new Set(e.map(e=>e.unitOrderTrait.waypointPath).filter(isNotNullOrUndefined))];if(t.length<=1){i={orderType:this.orderType,target:this.target,terminal:i.some(e=>e.terminal),next:void 0};if(0===t.length){let t={units:e,waypoints:[i]};e.forEach(e=>{e.unitOrderTrait.waypointPath=t})}else{let e=t[0];e.waypoints[e.waypoints.length-1].next=i,e.waypoints.push(i)}}}}}class SelectUnitsAction extends Action{get unitIds(){return this._unitIds}set unitIds(e){this._unitIds=e.slice(0,ORDER_UNIT_LIMIT)}constructor(e,t){super(ActionType.SelectUnits),this.game=e,this.orderActionContext=t}unserialize(t){let i=new DataStream(t);this.unitIds=new Array(t.byteLength/4);for(let e=0;e<t.byteLength/4;e++)this.unitIds[e]=i.readUint32()}serialize(){let e=new DataStream(4*this.unitIds.length);e.dynamicSize=!1;for(var t of this.unitIds)e.writeUint32(t);return e.toUint8Array()}print(){return`Select unit(s) [${this.unitIds.join(",")}]`}process(){let e=this.player,i=[];for(var r of this.unitIds){let t=e.getOwnedObjectById(r);if(!t&&this.game.getWorld().hasObjectId(r)){let e=this.game.getWorld().getObjectById(r);e.isTechno()&&(t=e)}t&&i.push(t)}this.orderActionContext.getOrCreateSelection(e).update(i)}}class SelectUnitsActionFactory{constructor(e,t){this.game=e,this.orderActionContext=t}create(){return new SelectUnitsAction(this.game,this.orderActionContext)}}class BuildingGarrisonEvent{constructor(e){this.target=e,this.type=EventType.BuildingGarrison}}class MoveOutsideTask extends MoveTask{constructor(e,t,i){super(e,i??t.tile,!1,{ignoredBlockers:[t]}),this.target=t,this.cancellable=!1}canStopAtTile(e,t,i){return!this.game.map.tileOccupation.isTileOccupiedBy(t,this.target)&&super.canStopAtTile(e,t,i)}}class MoveInsideTask extends MoveTask{static chooseTargetFoundationTile(t,i){if(t.isBuilding()){let e=t.centerTile;return i.map.mapBounds.isWithinBounds(e)||(e=i.map.tileOccupation.calculateTilesForGameObject(t.tile,t).find(e=>i.map.mapBounds.isWithinBounds(e))??t.tile),e}return t.tile}constructor(e,t){super(e,MoveInsideTask.chooseTargetFoundationTile(t,e),!1,{ignoredBlockers:[t],closeEnoughTiles:0}),this.target=t}hasReachedDestination(e){return super.hasReachedDestination(e)||this.canStopAtTile(e,e.tile,e.onBridge)}canStopAtTile(e,t,i){t=this.game.map.tileOccupation.isTileOccupiedBy(t,this.target);return(!this.isCancelling()||!t)&&!(!this.isCancelling()&&!t)}isCloseEnoughToDest(e,t,i){return this.game.map.tileOccupation.isTileOccupiedBy(t,this.target)}}class EnterObjectEvent{constructor(e,t){this.target=e,this.source=t,this.type=EventType.EnterObject}}class EnterBuildingTask extends Task{constructor(e,t){super(),this.game=e,this.target=t,this.aborted=!1,this.movePerformed=!1,this.preventOpportunityFire=!1}onTick(e){return!!(this.isCancelling()&&!this.movePerformed||this.aborted||e.moveTrait.isDisabled())||(this.movePerformed&&this.children.length?(e.tile===this.lastOutsideTile||this.game.map.tileOccupation.isTileOccupiedBy(e.tile,this.target)||(this.lastOutsideTile=e.tile),!1):this.game.map.tileOccupation.isTileOccupiedBy(e.tile,this.target)?!this.isAllowed(e)||this.isCancelling()?(this.children.push(new MoveOutsideTask(this.game,this.target,this.lastOutsideTile)),!(this.aborted=!0)):(this.game.events.dispatch(new EnterObjectEvent(this.target,e)),!1!==this.onEnter(e)||(this.children.push(new MoveOutsideTask(this.game,this.target,this.lastOutsideTile)),!(this.aborted=!0))):!!this.movePerformed||(this.children.push(new MoveInsideTask(this.game,this.target).setBlocking(!1)),this.movePerformed=!0,!(this.preventOpportunityFire=!0)))}getTargetLinesConfig(e){return{target:this.target,pathNodes:[]}}}class GarrisonBuildingTask extends EnterBuildingTask{isAllowed(e){return!this.target.isDestroyed&&!!this.target.garrisonTrait?.canBeOccupied()&&this.target.garrisonTrait.units.length<this.target.garrisonTrait.maxOccupants&&!(this.target.garrisonTrait.units.length&&this.target.garrisonTrait.units[0].owner!==e.owner)&&!e.mindControllableTrait?.isActive()}onEnter(e){this.game.limboObject(e,{selected:!1,controlGroup:this.game.getUnitSelection().getOrCreateSelectionModel(e).getControlGroupNumber()});let t=this.target.garrisonTrait;t.units.length||(e.owner.buildingsCaptured++,this.game.changeObjectOwner(this.target,e.owner),this.game.events.dispatch(new BuildingGarrisonEvent(this.target))),t.units.push(e)}}class UnitRecycleEvent{constructor(e){this.target=e,this.type=EventType.UnitRecycle}}class EnterRecyclerTask extends EnterBuildingTask{isAllowed(e){return e.rules.movementZone!==MovementZone.Fly&&e.rules.locomotor!==LocomotorType.Chrono&&!e.rules.engineer&&0<this.game.sellTrait.computeRefundValue(e)&&(e.isInfantry()&&this.target.rules.cloning||this.target.rules.grinding)&&!this.target.isDestroyed&&this.target.buildStatus===BuildStatus.Ready&&e.owner===this.target.owner}onEnter(e){this.game.sellTrait.sell(e),this.game.events.dispatch(new UnitRecycleEvent(e))}}class BuildingInfiltrationEvent{constructor(e,t){this.target=e,this.source=t,this.type=EventType.BuildingInfiltration}}class InfiltrateBuildingTask extends EnterBuildingTask{isAllowed(e){return e.rules.infiltrate&&this.target.rules.spyable&&!this.target.isDestroyed&&!this.game.areFriendly(e,this.target)}onEnter(e){this.game.unspawnObject(e),e.agentTrait?.infiltrate(e,this.target,this.game),this.game.events.dispatch(new BuildingInfiltrationEvent(this.target,e))}}!function(e){e[e.MoveToQueueingTile=0]="MoveToQueueingTile",e[e.WaitForTurn=1]="WaitForTurn",e[e.MoveToTarget=2]="MoveToTarget",e[e.EnterTarget=3]="EnterTarget",e[e.ClearTarget=4]="ClearTarget"}(EnterHospitalTask_State=EnterHospitalTask_State||{});class EnterHospitalTask extends Task{constructor(e,t){super(),this.game=e,this.target=t,this.movePerformed=!1}isAllowed(e){return e.rules.movementZone!==MovementZone.Fly&&e.healthTrait.health<100&&this.target.hospitalTrait&&!this.target.isDestroyed&&!this.target.warpedOutTrait.isActive()&&this.game.areFriendly(e,this.target)&&(!this.target.ammoTrait||0<this.target.ammoTrait.ammo)}onStart(e){if(!this.target.hospitalTrait)throw new Error(`Target ${this.target.name} is not a valid hospital`);0<this.target.hospitalTrait.addToHealQueue(e)?this.state=EnterHospitalTask_State.MoveToQueueingTile:this.state=EnterHospitalTask_State.MoveToTarget}onEnd(e){!this.target.isDestroyed&&e.isSpawned&&this.target.hospitalTrait.removeFromHealQueue(e)}onTick(i){if(this.isCancelling()&&this.state!==EnterHospitalTask_State.EnterTarget||this.state===EnterHospitalTask_State.ClearTarget||i.moveTrait.isDisabled())return!0;if(this.state===EnterHospitalTask_State.MoveToQueueingTile){let t=new MovePositionHelper(this.game.map);var e=new RadialTileFinder(this.game.map.tiles,this.game.map.mapBounds,this.target.tile,this.target.getFoundation(),1,1,e=>0<this.game.map.terrain.getPassableSpeed(e,i.rules.speedType,i.isInfantry(),!1)&&t.isEligibleTile(e,void 0,void 0,this.target.tile)).getNextTile();return!e||(this.children.push(new MoveTask(this.game,e,!1,{closeEnoughTiles:5})),this.children.push(new CallbackTask(()=>{[MoveResult.Success,MoveResult.CloseEnough].includes(i.moveTrait.lastMoveResult)||this.cancel()})),this.state=EnterHospitalTask_State.WaitForTurn,this.queueingTile=e,!1)}if(this.state===EnterHospitalTask_State.WaitForTurn){if(!this.target.hospitalTrait.unitIsFirstInHealQueue(i))return!1;this.queueingTile=void 0,this.state=EnterHospitalTask_State.MoveToTarget}if(this.state===EnterHospitalTask_State.MoveToTarget){if(this.movePerformed&&this.children.length)return i.tile===this.lastOutsideTile||this.game.map.tileOccupation.isTileOccupiedBy(i.tile,this.target)||(this.lastOutsideTile=i.tile),!1;if(!this.isAllowed(i))return!0;if(!this.game.map.tileOccupation.isTileOccupiedBy(i.tile,this.target))return!!this.movePerformed||(this.children.push(new MoveInsideTask(this.game,this.target).setBlocking(!1)),!(this.movePerformed=!0));this.state=EnterHospitalTask_State.EnterTarget}return this.state===EnterHospitalTask_State.EnterTarget&&(!this.isAllowed(i)||this.isCancelling()?(this.children.push(new MoveOutsideTask(this.game,this.target,this.lastOutsideTile)),this.state=EnterHospitalTask_State.ClearTarget,!1):(this.game.limboObject(i,{selected:!1,controlGroup:this.game.getUnitSelection().getOrCreateSelectionModel(i).getControlGroupNumber()}),this.target.hospitalTrait.startHealing(i),this.game.events.dispatch(new EnterObjectEvent(this.target,i)),!0))}getTargetLinesConfig(e){return{target:this.queueingTile?void 0:this.target,pathNodes:this.queueingTile?[{tile:this.queueingTile,onBridge:void 0}]:[]}}}class OccupyOrder extends Order{constructor(e){super(OrderType.Occupy),this.game=e,this.targetOptional=!1,this.terminal=!0,this.feedbackType=OrderFeedbackType.Capture}getPointerType(e){return e?this.isAllowed()?PointerType.OccupyMini:PointerType.NoActionMini:this.isAllowed()?PointerType.Occupy:PointerType.NoOccupy}isValid(){return!!(this.target.obj?.isSpawned&&this.target.obj?.isBuilding()&&this.sourceObject.isUnit())&&(!!this.isUnitRecycle(this.sourceObject,this.target.obj)||!!this.sourceObject.isInfantry()&&(this.target.obj.isBuilding()&&this.target.obj.hospitalTrait?this.game.areFriendly(this.sourceObject,this.target.obj)&&this.sourceObject.isInfantry():this.target.obj.garrisonTrait?this.target.obj.garrisonTrait.canBeOccupied()&&this.sourceObject.rules.occupier&&!(this.target.obj.garrisonTrait.units.length&&this.target.obj.garrisonTrait.units[0].owner!==this.sourceObject.owner)&&!this.sourceObject.mindControllableTrait?.isActive()&&!this.sourceObject.mindControllerTrait?.isActive():!(!this.target.obj.rules.spyable||!this.sourceObject.rules.infiltrate||this.game.areFriendly(this.sourceObject,this.target.obj))))}isUnitRecycle(e,t){return e.owner===t.owner&&(e.isInfantry()&&t.rules.cloning||t.rules.grinding)&&!e.rules.engineer}isAllowed(){var e=this.target.obj,t=this.sourceObject;return this.isUnitRecycle(t,e)?t.rules.movementZone!==MovementZone.Fly&&t.rules.locomotor!==LocomotorType.Chrono&&0<this.game.sellTrait.computeRefundValue(t):e.hospitalTrait?t.healthTrait.health<100&&t.rules.movementZone!==MovementZone.Fly:!e.garrisonTrait||e.garrisonTrait.units.length<e.rules.maxNumberOccupants}process(){var e=this.target.obj,t=this.sourceObject;return this.isUnitRecycle(t,e)?[new EnterRecyclerTask(this.game,e)]:e.hospitalTrait?[new EnterHospitalTask(this.game,e)]:e.garrisonTrait?[new GarrisonBuildingTask(this.game,e)]:[new InfiltrateBuildingTask(this.game,e)]}onAdd(t,e){if(!e){let e=t.find(e=>e instanceof GarrisonBuildingTask||e instanceof InfiltrateBuildingTask);if(this.isValid()&&this.isAllowed()&&e&&!e.isCancelling()&&e.target===this.target.obj)if(new RangeHelper(this.game.map.tileOccupation).isInTileRange(this.sourceObject,this.target.obj,0,Math.SQRT2))return!1}return!0}}class PlantC4Task extends EnterBuildingTask{isAllowed(e){return!this.target.isDestroyed&&!this.target.invulnerableTrait.isActive()}onEnter(e){var t=Math.floor(60*this.game.rules.combatDamage.c4Delay*GameSpeed.BASE_TICKS_PER_SECOND);return this.target.c4ChargeTrait.setCharge(t,{player:e.owner,obj:e}),this.game.events.dispatch(new EnterObjectEvent(this.target,e)),!1}getTargetLinesConfig(e){return{target:this.target,pathNodes:[],isAttack:!0}}}class AttackOrder extends Order{constructor(e,{forceAttack:t,noIvanBomb:i}={}){super(t?OrderType.ForceAttack:OrderType.Attack),this.game=e,this.isC4=!1,this.forceAttack=!!t,this.ivanBombAllowed=!i||!!t,this.targetOptional=!1,this.feedbackType=OrderFeedbackType.None,this.rangeHelper=new RangeHelper(this.game.map.tileOccupation),this.losHelper=new LosHelper(this.game.map.tiles,e.map.tileOccupation)}getPointerType(e,t){if(!this.isAllowed())return e?PointerType.NoActionMini:PointerType.NoAction;if(this.isC4)return PointerType.C4;var i=this.sourceObject.attackTrait?.selectWeaponVersus(this.sourceObject,this.target,this.game,this.forceAttack);if(i?.rules.sabotageCursor)return PointerType.C4;if(this.ivanBombAllowed&&this.sourceObject.rules.ivan&&i?.warhead.rules.ivanBomb)return PointerType.Dynamite;if(i?.warhead.rules.bombDisarm)return PointerType.DefuseBomb;if(i&&i.rules.damage<0)return PointerType.RepairMove;t=t.every(e=>{if(!e.attackTrait)return!0;var t=e.attackTrait.selectWeaponVersus(e,this.target,this.game,this.forceAttack);return!t||this.rangeHelper.isInWeaponRange(e,this.target.obj||this.target.tile,t,this.game.rules)&&this.losHelper.hasLineOfSight(e,this.target.obj||this.target.tile,t)});return e?PointerType.AttackMini:t?PointerType.AttackRange:PointerType.AttackNoRange}isValid(){if(!this.sourceObject.attackTrait)return!1;if(this.forceAttack&&this.game.mapShroudTrait.getPlayerShroud(this.sourceObject.owner)?.isShrouded(this.target.tile,this.target.obj?.tileElevation)&&!this.sourceObject.isBuilding())return!1;let e=this.target.obj;var t=this.game.map.getGroundObjectsOnTile(this.target.tile).find(e=>e.isTerrain());if(this.terminal=!e&&!t,this.sourceObject.c4&&e?.isBuilding()&&e.c4ChargeTrait&&(this.forceAttack||!this.game.areFriendly(e,this.sourceObject)||e.cabHutTrait))return this.isC4=!0,this.feedbackType=OrderFeedbackType.SpecialAttack,!0;if(this.isC4=!1,this.feedbackType=OrderFeedbackType.Attack,!this.game.isValidTarget(e))return!1;if(!e&&t?.rules.immune)return!1;if(!(e||this.target.tile!==this.sourceObject.tile||this.sourceObject.isUnit()&&this.sourceObject.zone===ZoneType.Air))return!1;if(e===this.sourceObject)return!1;t=this.sourceObject.attackTrait.selectWeaponVersus(this.sourceObject,this.target,this.game,this.forceAttack);return!!t&&(!(!this.ivanBombAllowed&&t.warhead.rules.ivanBomb)&&(!(e?.isBuilding()&&e.cabHutTrait&&!t.warhead.rules.ivanBomb&&!t.warhead.rules.bombDisarm)&&(!!(this.sourceObject.isUnit()&&this.sourceObject.moveTrait&&!this.sourceObject.moveTrait.isDisabled()||this.rangeHelper.isInWeaponRange(this.sourceObject,e||this.target.tile,t,this.game.rules))&&(!(this.sourceObject.airSpawnTrait&&t.rules.spawner&&!this.game.map.isWithinBounds(this.target.tile))&&(!!this.forceAttack||(!e?.isBuilding()||!e.hospitalTrait)&&(!(!e||!e.healthTrait)&&(!e.isDestroyed&&!e.isCrashing&&(!(!e.isOverlay()||!(t.warhead.rules.wall||t.warhead.rules.wood&&e.rules.armor===ArmorType.Wood))||e.isTechno()))))))))}isAllowed(){return!this.sourceObject.attackTrait.isDisabled()}process(){if(this.isC4)return[new PlantC4Task(this.game,this.target.obj)];var e=this.sourceObject.attackTrait.selectWeaponVersus(this.sourceObject,this.target,this.game,this.forceAttack);return[new AttackTask(this.game,this.target,e,{force:this.forceAttack})]}onAdd(t,i){let r=this.sourceObject;if(!i&&r.isUnit()&&this.isValid()&&this.isAllowed())if(r.rules.movementZone===MovementZone.Fly){var s=t.find(e=>(e.constructor===MoveTask||e.constructor===AttackTask)&&!e.isCancelling());let e;s&&(r.moveTrait.currentWaypoint?.tile===this.target.tile||r.isAircraft()||s.constructor===AttackTask||(i=this.sourceObject.attackTrait.selectWeaponVersus(this.sourceObject,this.target,this.game,this.forceAttack)).projectileRules.vertical&&s.constructor===MoveTask&&this.rangeHelper.isInWeaponRange(this.sourceObject,this.target.obj||this.target.tile,i,this.game.rules))&&(e=s),e?.forceCancel(r)&&t.splice(t.indexOf(e))}else{t.length&&r.isUnit()&&(r.rules.locomotor===LocomotorType.Vehicle||r.rules.locomotor===LocomotorType.Ship)&&(r.moveTrait.speedPenalty=.5);let e=t.find(e=>e.constructor===AttackTask&&!e.isCancelling());if(e?.getWeapon().warhead.rules.temporal)return e.setForceAttack(this.forceAttack),e.requestTargetUpdate(this.target),!1}return!0}}class StopOrder extends Order{constructor(e){super(OrderType.Stop),this.game=e,this.getPointerType=()=>PointerType.NoAction}isValid(){return this.sourceObject.isTechno()}isAllowed(){return!0}process(){return[new CallbackTask(e=>{!e.isUnit()||e.rules.locomotor!==LocomotorType.Vehicle&&e.rules.locomotor!==LocomotorType.Ship||(e.moveTrait.speedPenalty=0)})]}onAdd(e,t){let i=this.sourceObject;return t||!e.length||!i.isUnit()||i.rules.locomotor!==LocomotorType.Vehicle&&i.rules.locomotor!==LocomotorType.Ship||(i.moveTrait.speedPenalty=.5),i.isBuilding()&&i.rallyTrait?.getRallyPoint()&&(i.unitRepairTrait?.resetRallyPoint(i,this.game),i.factoryTrait?.resetRallyPoint(i,this.game)),!0}}class CheerOrder extends Order{constructor(){super(OrderType.Cheer),this.getPointerType=()=>PointerType.NoAction}isValid(){return this.sourceObject.isInfantry()&&[StanceType.None,StanceType.Guard].includes(this.sourceObject.stance)}isAllowed(){return!0}process(){return[new CheerTask]}}class DockOrder extends Order{constructor(e){super(OrderType.Dock),this.game=e,this.targetOptional=!1,this.feedbackType=OrderFeedbackType.Move}getPointerType(e){return e?this.isAllowed()?PointerType.OccupyMini:PointerType.NoActionMini:this.isAllowed()?PointerType.Occupy:PointerType.NoOccupy}isValid(){if(!this.target.obj?.isBuilding()||this.target.obj.isDestroyed||!this.target.obj.dockTrait||this.target.obj.buildStatus!==BuildStatus.Ready||!this.sourceObject.isUnit()||this.target.obj.warpedOutTrait.isActive())return!1;var e=!(this.target.obj.rules.refinery||this.target.obj.unitRepairTrait);return this.game.areFriendly(this.target.obj,this.sourceObject)&&this.target.obj.dockTrait.isValidUnitForDock(this.sourceObject)&&!this.target.obj.dockTrait.isDocked(this.sourceObject)&&!(this.target.obj.unitRepairTrait&&!this.sourceObject.rules.dock.includes(this.target.obj.name)&&100===this.sourceObject.healthTrait.health)&&(!e||(0<(this.target.obj.dockTrait.getAvailableDockCount()??0)||this.target.obj.dockTrait.hasReservedDockForUnit(this.sourceObject)))}isAllowed(){return!0}process(){var e=this.target.obj;return e.rules.refinery&&this.sourceObject.isVehicle()&&this.sourceObject.harvesterTrait?[new ReturnOreTask(this.game,e,!0,!0)]:e.unitRepairTrait||this.sourceObject.rules.dock.includes(e.name)?[new MoveToDockTask(this.game,e)]:[]}}class GatherOrder extends Order{constructor(e){super(OrderType.Gather),this.game=e,this.targetOptional=!1,this.feedbackType=OrderFeedbackType.Move}getPointerType(e){return e?PointerType.AttackMini:PointerType.AttackNoRange}isValid(){return!(!this.sourceObject.isVehicle()||!this.sourceObject.harvesterTrait||this.sourceObject.moveTrait.isDisabled()||this.game.mapShroudTrait.getPlayerShroud(this.sourceObject.owner)?.isShrouded(this.target.tile,this.target.obj?.tileElevation))&&this.target.isOre}isAllowed(){return!0}process(){return[new GatherOreTask(this.game,this.target.tile,!0)]}}class AttackMoveOrder extends AttackOrder{constructor(e,t){super(e),this.map=t,this.orderType=OrderType.AttackMove,this.targetOptional=!1,this.feedbackType=OrderFeedbackType.Move}getPointerType(t,i){if(this.isTargetted()){let e=super.getPointerType(t,i);return e!==PointerType.AttackRange&&e!==PointerType.AttackNoRange||(e=PointerType.AttackMove),e}let e=this.isAllowed();var r,s,a;return e&&(r=!!this.target.getBridge(),s=this.sourceObject.rules.speedType,a=this.sourceObject.isInfantry(),i=this.sourceObject.rules.movementZone===MovementZone.Fly,e=i||0<this.map.terrain.getPassableSpeed(this.target.tile,s,a,r)||!!this.game.mapShroudTrait.getPlayerShroud(this.sourceObject.owner)?.isShrouded(this.target.tile,this.target.obj?.tileElevation)),t?e?PointerType.AttackMini:PointerType.NoActionMini:e?PointerType.AttackMove:PointerType.NoMove}isValid(){var e=this.sourceObject.isUnit()&&!!this.sourceObject.attackTrait&&!this.sourceObject.rules.preventAttackMove&&!(this.game.mapShroudTrait.getPlayerShroud(this.sourceObject.owner)?.isShrouded(this.target.tile,this.target.obj?.tileElevation)&&!this.sourceObject.rules.moveToShroud)&&(!this.isTargetted()||super.isValid());return this.feedbackType=OrderFeedbackType.Move,e}isAllowed(){return!(!this.isTargetted()&&this.sourceObject.moveTrait.isDisabled())&&super.isAllowed()}process(){if(this.isTargetted()){if(this.isC4)return[new PlantC4Task(this.game,this.target.obj)];var e=this.sourceObject.attackTrait.selectWeaponVersus(this.sourceObject,this.target,this.game);return[new AttackMoveTargetTask(this.game,this.target,e)]}return[new AttackMoveTask(this.game,this.target.tile,!!this.target.getBridge(),{closeEnoughTiles:this.game.rules.general.closeEnough})]}isTargetted(){return this.target.obj?.isTechno()}onAdd(t,e){let i=this.sourceObject;if(!e&&i.isUnit()&&this.isValid()&&this.isAllowed())if(i.rules.movementZone===MovementZone.Fly){let e=t.find(e=>[MoveTask,AttackTask,AttackMoveTask,AttackMoveTargetTask].includes(e.constructor)&&!e.isCancelling());if(e)if(this.isTargetted())(i.moveTrait.currentWaypoint?.tile===this.target.tile||i.isAircraft()||e.constructor!==MoveTask)&&e.forceCancel(i)&&t.splice(t.indexOf(e));else{if(e.constructor===AttackMoveTask)return e.updateTarget(this.target.tile,!!this.target.getBridge()),t.splice(t.indexOf(e)+1),i.unitOrderTrait.clearOrders(),!1;e.forceCancel(i)&&t.splice(t.indexOf(e))}}else this.isTargetted()&&t.length&&i.isUnit()&&(i.rules.locomotor===LocomotorType.Vehicle||i.rules.locomotor===LocomotorType.Ship)&&(i.moveTrait.speedPenalty=.5);return!0}}class BuildingRepairFullEvent{constructor(e,t){this.target=e,this.source=t,this.type=EventType.BuildingRepairFull}}class BridgeRepairEvent{constructor(e,t){this.source=e,this.tile=t,this.type=EventType.BridgeRepair}}class RepairBuildingTask extends EnterBuildingTask{isAllowed(e){return this.target.cabHutTrait?this.target.cabHutTrait.canRepairBridge():e.rules.engineer&&!this.target.isDestroyed&&this.target.rules.repairable&&this.target.healthTrait.health<100&&(!this.target.owner.isCombatant()&&!!this.target.garrisonTrait||this.game.areFriendly(e,this.target))}onEnter(e){this.game.unspawnObject(e),this.target.cabHutTrait?(this.target.cabHutTrait.repairBridge(this.game,e.owner),this.game.events.dispatch(new BridgeRepairEvent(e.owner,this.target.centerTile))):(this.target.healthTrait.healToFull(e,this.game),this.game.events.dispatch(new BuildingRepairFullEvent(this.target,e.owner)))}}class RepairOrder extends Order{constructor(e){super(OrderType.Repair),this.game=e,this.targetOptional=!1,this.terminal=!0,this.feedbackType=OrderFeedbackType.Capture}getPointerType(e){return e?this.isAllowed()?PointerType.OccupyMini:PointerType.NoActionMini:this.isAllowed()?PointerType.RepairMove:PointerType.NoRepair}isValid(){return!!this.target.obj?.isBuilding()&&!this.target.obj.isDestroyed&&this.sourceObject.isInfantry()&&this.sourceObject.rules.engineer&&(!this.target.obj.owner.isCombatant()&&(!!this.target.obj.garrisonTrait||!!this.target.obj.cabHutTrait)||this.game.areFriendly(this.target.obj,this.sourceObject))}isAllowed(){let e=this.target.obj;return e.cabHutTrait?e.cabHutTrait.canRepairBridge():!!(e.rules.repairable&&e.healthTrait.health<100)}process(){var e=this.target.obj;return[new RepairBuildingTask(this.game,e)]}onAdd(t,e){if(!e){let e=t.find(e=>e instanceof RepairBuildingTask);if(this.isValid()&&this.isAllowed()&&e&&!e.isCancelling()&&e.target===this.target.obj)if(new RangeHelper(this.game.map.tileOccupation).isInTileRange(this.sourceObject,this.target.obj,0,Math.SQRT2))return!1}return!0}}class GuardAreaOrder extends Order{constructor(e,t){super(t?OrderType.GuardArea:OrderType.Guard),this.game=e,this.targeted=t,this.getPointerType=e=>e?this.isAllowed()?PointerType.GuardMini:PointerType.NoActionMini:this.isAllowed()?PointerType.Guard:PointerType.NoMove,this.terminal=!0,this.targetOptional=!t,this.minimapAllowed=t,this.feedbackType=t?OrderFeedbackType.Move:OrderFeedbackType.None}isValid(){return this.sourceObject.isUnit()&&(!!this.targetOptional||!this.sourceObject.moveTrait.isDisabled())&&!(this.target&&this.game.mapShroudTrait.getPlayerShroud(this.sourceObject.owner)?.isShrouded(this.target.tile,this.target.obj?.tileElevation)&&!this.sourceObject.rules.moveToShroud)}isAllowed(){return!0}process(){let t=this.targeted?this.target.tile:void 0;const e=this.sourceObject;let i=[];return t&&i.push(new MoveTask(this.game,t,!!this.target.getBridge(),{closeEnoughTiles:this.game.rules.general.closeEnough})),e.isVehicle()&&e.harvesterTrait?i.push(new CallbackTask(()=>e.harvesterTrait.lastOreSite=void 0),new GatherOreTask(this.game,void 0,!0)):i.push(new CallbackTask(e=>{t&&![MoveResult.Success,MoveResult.CloseEnough].includes(this.sourceObject.moveTrait?.lastMoveResult)||(this.sourceObject.guardMode=!0)})),i}}class ScatterOrder extends Order{constructor(e){super(OrderType.Scatter),this.game=e,this.getPointerType=()=>PointerType.NoAction}isValid(){return(this.sourceObject.isInfantry()||this.sourceObject.isVehicle())&&this.sourceObject.rules.movementZone!==MovementZone.Fly&&!this.sourceObject.moveTrait.isDisabled()}isAllowed(){return!0}process(){if(!this.target)throw new Error("Target should be set for executing a scatter order. See OrderUnitsAction.");return[new ScatterTask(this.game,{tile:this.target.tile,toBridge:!!this.target.getBridge()})]}}class EnterTransportEvent{constructor(e){this.target=e,this.type=EventType.EnterTransport}}!function(e){e[e.MoveToQueueingTile=0]="MoveToQueueingTile",e[e.WaitForTurn=1]="WaitForTurn",e[e.MoveToTransport=2]="MoveToTransport",e[e.EnterTransport=3]="EnterTransport",e[e.ClearTransport=4]="ClearTransport"}(EnterTransportTask_State=EnterTransportTask_State||{});class EnterTransportTask extends Task{constructor(e,t){super(),this.game=e,this.target=t,this.movePerformed=!1,this.preventOpportunityFire=!1}isAllowed(e){return!this.target.isDestroyed&&!this.target.isCrashing&&this.game.areFriendly(this.target,e)&&e.zone!==ZoneType.Air&&this.target.zone!==ZoneType.Air&&this.target.transportTrait.unitFitsInside(e)&&this.target.moveTrait.moveState===MoveState.Idle&&!this.target.warpedOutTrait.isActive()&&!e.mindControllableTrait?.isActive()&&!e.mindControllerTrait?.isActive()}onStart(e){if(!this.target.transportTrait)throw new Error(`Unit ${this.target.name} is not a valid transport`);this.initialTargetTile=this.target.tile,0<this.target.transportTrait.addToLoadQueue(e)?this.state=EnterTransportTask_State.MoveToQueueingTile:this.state=EnterTransportTask_State.MoveToTransport}onEnd(e){this.target.isDestroyed||this.target.transportTrait?.removeFromLoadQueue(e)}onTick(n){if(this.isCancelling()&&this.state!==EnterTransportTask_State.EnterTransport||this.state===EnterTransportTask_State.ClearTransport||n.moveTrait.isDisabled())return!0;if(this.target.tile!==this.initialTargetTile||this.target.moveTrait.moveState!==MoveState.Idle)return!0;if(this.state===EnterTransportTask_State.MoveToQueueingTile){let r=new MovePositionHelper(this.game.map),s=this.target.onBridge?this.game.map.tileOccupation.getBridgeOnTile(this.target.tile):void 0,a;var e=new RadialTileFinder(this.game.map.tiles,this.game.map.mapBounds,this.target.tile,this.target.getFoundation(),1,1,e=>{let t=[this.game.map.tileOccupation.getBridgeOnTile(e)];t[0]&&t.push(void 0);for(var i of t)if(0<this.game.map.terrain.getPassableSpeed(e,n.rules.speedType,n.isInfantry(),!!i)&&r.isEligibleTile(e,i,s,this.target.tile))return a=i,!0;return!1}).getNextTile();return!e||(this.children.push(new MoveTask(this.game,e,!!a,{closeEnoughTiles:5})),this.children.push(new CallbackTask(()=>{[MoveResult.Success,MoveResult.CloseEnough].includes(n.moveTrait.lastMoveResult)||this.cancel()})),this.queueingNode={tile:e,onBridge:a},this.state=EnterTransportTask_State.WaitForTurn,!1)}if(this.state===EnterTransportTask_State.WaitForTurn){if(!this.target.transportTrait.unitIsFirstInLoadQueue(n))return!1;this.queueingNode=void 0,this.state=EnterTransportTask_State.MoveToTransport}if(this.state===EnterTransportTask_State.MoveToTransport){if(!this.isAllowed(n))return!0;if(!this.game.map.tileOccupation.isTileOccupiedBy(n.tile,this.target))return!!this.movePerformed||(this.children.push(new MoveInsideTask(this.game,this.target)),this.movePerformed=!0,!(this.preventOpportunityFire=!0));this.state=EnterTransportTask_State.EnterTransport}return this.state===EnterTransportTask_State.EnterTransport&&(!this.isAllowed(n)||this.isCancelling()?(this.children.push(new MoveOutsideTask(this.game,this.target)),this.state=EnterTransportTask_State.ClearTransport,!1):(this.game.limboObject(n,{selected:!1,controlGroup:this.game.getUnitSelection().getOrCreateSelectionModel(n).getControlGroupNumber(),inTransport:!0}),this.game.events.dispatch(new EnterTransportEvent(this.target)),this.game.events.dispatch(new EnterObjectEvent(this.target,n)),this.target.transportTrait.units.push(n),!0))}getTargetLinesConfig(e){return{target:this.queueingNode?void 0:this.target,pathNodes:this.queueingNode?[this.queueingNode]:[]}}}class EnterTransportOrder extends Order{constructor(e){super(OrderType.EnterTransport),this.game=e,this.targetOptional=!1,this.terminal=!0,this.feedbackType=OrderFeedbackType.Enter}getPointerType(e){return e?this.isAllowed()?PointerType.OccupyMini:PointerType.NoActionMini:this.isAllowed()?PointerType.Occupy:PointerType.NoOccupy}isValid(){return!(!this.target.obj?.isVehicle()||!this.target.obj.transportTrait||this.target.obj.isDestroyed||this.target.obj===this.sourceObject||!this.game.areFriendly(this.target.obj,this.sourceObject)||!this.sourceObject.isVehicle()&&!this.sourceObject.isInfantry())}isAllowed(){let e=this.target.obj,t=this.sourceObject;return t.zone!==ZoneType.Air&&e.zone!==ZoneType.Air&&e.transportTrait.unitFitsInside(t)&&e.moveTrait.moveState===MoveState.Idle&&!e.warpedOutTrait.isActive()&&!t.mindControllableTrait?.isActive()&&!t.mindControllerTrait?.isActive()}process(){let e=this.sourceObject,t=this.target.obj;return this.game.map.terrain.getPassableSpeed(t.tile,e.rules.speedType,e.isInfantry(),e.onBridge)?[new EnterTransportTask(this.game,t)]:[new CallbackTask(()=>{t.unitOrderTrait.addTask(new MoveTask(this.game,e.tile,e.onBridge)),t.unitOrderTrait.addTask(new CallbackTask(()=>{this.game.map.terrain.getPassableSpeed(t.tile,e.rules.speedType,e.isInfantry(),e.onBridge)&&e.unitOrderTrait.addTask(new EnterTransportTask(this.game,t))}))})]}onAdd(t,e){if(!e){let e=t.find(e=>e instanceof EnterTransportTask);if(this.isValid()&&this.isAllowed()&&e&&!e.isCancelling()&&e.target===this.target.obj)if(new RangeHelper(this.game.map.tileOccupation).isInTileRange(this.sourceObject,this.target.obj,0,Math.SQRT2))return!1}return!0}}class BuildingCaptureEvent{constructor(e){this.target=e,this.type=EventType.BuildingCapture}}class CaptureBuildingTask extends EnterBuildingTask{isAllowed(e){return e.rules.engineer&&this.target.rules.capturable&&!this.target.isDestroyed&&this.target.buildStatus!==BuildStatus.BuildDown&&!this.game.areFriendly(e,this.target)}onEnter(t){if(this.game.unspawnObject(t),this.game.gameOpts.multiEngineer){var i=this.game.rules.general;if((!this.target.rules.needsEngineer||!i.engineerAlwaysCaptureTech)&&this.target.healthTrait.health>100*i.engineerCaptureLevel){var r=Math.floor(i.engineerDamage*this.target.healthTrait.maxHitPoints),i=Math.floor((1-Math.floor(1/i.engineerDamage)*i.engineerDamage)*this.target.healthTrait.maxHitPoints);if(0<(r=Math.min(r,this.target.healthTrait.getHitPoints()-i))){i=this.game.rules.combatDamage.c4Warhead;let e=new Warhead(this.game.rules.getWarhead(i));return void e.detonate(this.game,r,this.target.tile,0,this.target.position.worldPosition,ZoneType.Ground,CollisionType.None,this.game.createTarget(this.target,this.target.tile),{player:t.owner,obj:t,weapon:void 0},SpecialWarheadType.None,void 0,0)}}}t.owner.buildingsCaptured++,this.game.changeObjectOwner(this.target,t.owner),this.game.events.dispatch(new BuildingCaptureEvent(this.target))}}class CaptureOrder extends Order{constructor(e){super(OrderType.Capture),this.game=e,this.targetOptional=!1,this.terminal=!0,this.feedbackType=OrderFeedbackType.Capture}getPointerType(e){if(!this.isAllowed())return e?PointerType.NoActionMini:PointerType.NoOccupy;if(e)return PointerType.OccupyMini;if(this.game.gameOpts.multiEngineer){var t=this.game.rules.general,e=this.target.obj;if((!e.rules.needsEngineer||!t.engineerAlwaysCaptureTech)&&e.healthTrait.health>100*t.engineerCaptureLevel)return PointerType.EngineerDamage}return PointerType.Occupy}isValid(){return!(this.target.obj?.isDestroyed||!this.target.obj?.isBuilding()||!this.sourceObject.isInfantry())&&(this.target.obj.rules.capturable&&this.sourceObject.rules.engineer&&!this.game.areFriendly(this.sourceObject,this.target.obj))}isAllowed(){return!0}process(){return[new CaptureBuildingTask(this.game,this.target.obj)]}onAdd(t,e){if(!e){let e=t.find(e=>e instanceof CaptureBuildingTask);if(this.isValid()&&this.isAllowed()&&e&&!e.isCancelling()&&e.target===this.target.obj)if(new RangeHelper(this.game.map.tileOccupation).isInTileRange(this.sourceObject,this.target.obj,0,Math.SQRT2))return!1}return!0}}class OrderFactory{constructor(e,t){this.game=e,this.map=t}create(e,t){switch(e){case OrderType.Deploy:return new DeployOrder(this.game,!0);case OrderType.DeploySelected:return new DeployOrder(this.game,!1);case OrderType.ForceMove:return new MoveOrder(this.game,this.map,t,!0);case OrderType.Move:return new MoveOrder(this.game,this.map,t);case OrderType.ForceAttack:return new AttackOrder(this.game,{forceAttack:!0});case OrderType.Attack:return new AttackOrder(this.game,{noIvanBomb:!0});case OrderType.PlaceBomb:return new AttackOrder(this.game);case OrderType.AttackMove:return new AttackMoveOrder(this.game,this.map);case OrderType.Capture:return new CaptureOrder(this.game);case OrderType.Occupy:return new OccupyOrder(this.game);case OrderType.Stop:return new StopOrder(this.game);case OrderType.Cheer:return new CheerOrder;case OrderType.Dock:return new DockOrder(this.game);case OrderType.Gather:return new GatherOrder(this.game);case OrderType.Repair:return new RepairOrder(this.game);case OrderType.Guard:return new GuardAreaOrder(this.game,!1);case OrderType.GuardArea:return new GuardAreaOrder(this.game,!0);case OrderType.Scatter:return new ScatterOrder(this.game);case OrderType.EnterTransport:return new EnterTransportOrder(this.game);default:throw new Error("Unhandled order type "+OrderType[e])}}}class OrderUnitsActionFactory{constructor(e,t,i){this.game=e,this.map=t,this.orderActionContext=i}create(){return new OrderUnitsAction(this.game,this.map,this.orderActionContext,new OrderFactory(this.game,this.map))}}!function(e){e[e.Add=0]="Add",e[e.Cancel=1]="Cancel",e[e.Pause=2]="Pause",e[e.Resume=3]="Resume",e[e.AddNext=4]="AddNext"}(UpdateType=UpdateType||{});class UpdateQueueAction extends Action{constructor(e){super(ActionType.UpdateQueue),this.game=e}unserialize(e){let t=new DataStream(e);var i;this.queueType=t.readUint8(),this.updateType=t.readUint8(),this.updateType!==UpdateType.Add&&this.updateType!==UpdateType.Cancel&&this.updateType!==UpdateType.AddNext||(i=t.readUint32(),e=t.readUint8(),this.item=this.game.rules.getTechnoByInternalId(i,e),this.quantity=t.readUint16())}serialize(){let e=new DataStream(9);if(e.dynamicSize=!1,e.writeUint8(this.queueType),e.writeUint8(this.updateType),this.updateType===UpdateType.Add||this.updateType===UpdateType.Cancel||this.updateType===UpdateType.AddNext){if(void 0===this.quantity)throw new Error("Missing quantity");if(65535<this.quantity)throw new Error("Maximum quantity exceeded");e.writeUint32(this.item.index),e.writeUint8(this.item.type),e.writeUint16(this.quantity)}return new Uint8Array(e.buffer,e.byteOffset,e.position)}print(){return this.updateType===UpdateType.Resume?"Resume queue "+QueueType[this.queueType]:this.updateType===UpdateType.Add?`Add to queue ${this.item.name} x `+this.quantity:this.updateType===UpdateType.AddNext?`Add next in queue ${this.item.name} x `+this.quantity:this.updateType===UpdateType.Pause?`Put queue ${QueueType[this.queueType]} on hold.`:this.updateType===UpdateType.Cancel?`Cancel ${this.item.name} x `+this.quantity:"Unhandled queue update type "+this.updateType}process(){let i=this.player,r=this.item,s=i.production.getQueue(this.queueType);if(this.updateType===UpdateType.Resume)s.status===QueueStatus.OnHold&&(s.status=QueueStatus.Active);else if(this.updateType===UpdateType.Add||this.updateType===UpdateType.AddNext){let e=s.find(r);if(s.status===QueueStatus.Active||s.status===QueueStatus.Idle||s.status===QueueStatus.OnHold&&e[0]!==s.getFirst()||s.status===QueueStatus.Ready&&r.type!==ObjectType.Building){let t;var a=e.reduce((e,t)=>e+t.quantity,0);if(Number.isFinite(r.buildLimit)){let e;e=0<=r.buildLimit?i.getOwnedObjectsByType(r.type,!0).filter(e=>e.name===r.name).length:i.getLimitedUnitsBuilt(r.name),t=Math.max(0,Math.abs(r.buildLimit)-(e+a))}else t=Number.POSITIVE_INFINITY;t&&i.production.isAvailableForProduction(r)&&(n=Math.min(s.maxSize-s.currentSize,s.maxItemQuantity-a,t),0<(o=Math.min(this.quantity,n))&&(this.updateType===UpdateType.AddNext?s.insertAfterFirst(r,o,r.cost):s.push(r,o,r.cost)))}}else if(this.updateType===UpdateType.Cancel){if([QueueStatus.Ready,QueueStatus.OnHold,QueueStatus.Active].includes(s.status)){let e=s.find(r);var n,o;e.length&&(n=e.reduce((e,t)=>e+t.quantity,0),0<(o=Math.min(n,this.quantity))&&(s.pop(r,o),o===n&&(i.credits+=e[0].creditsSpent)))}}else this.updateType===UpdateType.Pause&&s.status===QueueStatus.Active&&(s.status=QueueStatus.OnHold)}}class UpdateQueueActionFactory{constructor(e){this.game=e}create(){return new UpdateQueueAction(this.game)}}class PlayerDroppedEvent{constructor(e,t){this.target=e,this.assetsRedistributed=t,this.type=EventType.PlayerDropped}}class DropPlayerAction extends Action{constructor(e,t){super(ActionType.DropPlayer),this.game=e,this.localPlayerName=t}process(){if(this.localPlayerName!==this.player.name){let e=this.player;var t;e.defeated||(t=this.game.redistributeAllPlayerAssets(e),this.game.removeAllPlayerAssets(e),e.dropped=!0,this.game.events.dispatch(new PlayerDroppedEvent(e,t)))}}}class DropPlayerActionFactory{constructor(e,t){this.game=e,this.localPlayerName=t}create(){return new DropPlayerAction(this.game,this.localPlayerName)}}class BuildingRepairStartEvent{constructor(e){this.target=e,this.type=EventType.BuildingRepairStart}}class ToggleRepairAction extends Action{constructor(e){super(ActionType.ToggleRepair),this.game=e}unserialize(e){this.buildingId=new DataStream(e).readUint32()}serialize(){return new DataStream(4).writeUint32(this.buildingId).toUint8Array()}print(){return"Toggle repair "+this.buildingId}process(){var e=this.player;if(this.game.getWorld().hasObjectId(this.buildingId)){let t=this.game.getObjectById(this.buildingId);if(t.isBuilding()&&e===t.owner&&!t.isDestroyed&&t.rules.repairable&&t.rules.clickRepairable&&100!==t.healthTrait.health){let e=t.traits.get(AutoRepairTrait);e.setDisabled(!e.isDisabled()),e.isDisabled()||this.game.events.dispatch(new BuildingRepairStartEvent(t))}}}}class ToggleRepairActionFactory{constructor(e){this.game=e}create(){return new ToggleRepairAction(this.game)}}class ToggleAllianceAction extends Action{constructor(e){super(ActionType.ToggleAlliance),this.game=e}unserialize(e){this.toPlayer=this.game.getPlayer(e[0]),this.toggle=Boolean(e[1])}serialize(){return new Uint8Array([this.game.getPlayerNumber(this.toPlayer),this.toggle?1:0])}print(){return`Toggle alliance ${this.toggle?"on":"off"} with `+this.toPlayer.name}process(){var e=this.game.rules.mpDialogSettings;if(e.alliesAllowed&&e.allyChangeAllowed){var a,n=this.player,t=this.toPlayer,e=this.toggle;let i=n,r=t,s=this.game.alliances;if(!n.defeated&&s.canRequestAlliance(r)){let t=s.findByPlayers(i,r);t?t.status===AllianceStatus.Formed?e||(s.breakAlliance(i,r),this.game.onAllianceChange(t,i,!1)):t.status===AllianceStatus.Requested&&(t.players.first===r?e&&s.canFormAlliance(i,r)&&(s.acceptRequest(r,i),this.game.onAllianceChange(t,i,!0),1!==(n=this.game.getCombatants().filter(e=>e!==i&&!s.areAllied(i,e))).length||(a=s.findByPlayers(n[0],i))&&s.cancelRequest(a.players.first,a.players.second),1!==(a=this.game.getCombatants().filter(e=>e!==r&&!s.areAllied(r,e))).length||(a=s.findByPlayers(a[0],r))&&s.cancelRequest(a.players.first,a.players.second)):e||(s.cancelRequest(i,r),this.game.events.dispatch(new AllianceChangeEvent(t,AllianceEventType.Broken,i)),this.game.traits.filter(NotifyAllianceChange).forEach(e=>{e[NotifyAllianceChange.onChange](t,!1,this.game)}))):e&&s.canFormAlliance(i,r)&&((e=s.request(i,r))&&this.game.events.dispatch(new AllianceChangeEvent(e,AllianceEventType.Requested,i)))}}}}class ToggleAllianceActionFactory{constructor(e){this.game=e}create(){return new ToggleAllianceAction(this.game)}}class ActivateSuperWeaponAction extends Action{constructor(e){super(ActionType.ActivateSuperWeapon),this.game=e}unserialize(e){let t=new DataStream(e);this.superWeaponType=t.readUint8();e=t.readUint8();this.tile={x:t.readUint16(),y:t.readUint16()},this.tile2=2<e?{x:t.readUint16(),y:t.readUint16()}:void 0}serialize(){let e=new DataStream(6+(this.tile2?4:0));return e.dynamicSize=!1,e.writeUint8(this.superWeaponType),e.writeUint8(this.tile2?4:2),e.writeUint16(this.tile.x),e.writeUint16(this.tile.y),this.tile2&&(e.writeUint16(this.tile2.x),e.writeUint16(this.tile2.y)),e.toUint8Array()}print(){return`Activate SuperW ${SuperWeaponType[this.superWeaponType]} at tile (${this.tile.x}, ${this.tile.y})`+(this.tile2?`, (${this.tile2.x}, ${this.tile2.y})`:"")}process(){var e,t=this.player,i=this.game.map.tiles.getByMapCoords(this.tile.x,this.tile.y);i?(e=this.tile2?this.game.map.tiles.getByMapCoords(this.tile2.x,this.tile2.y):void 0,this.game.traits.get(SuperWeaponsTrait).activateSuperWeapon(this.superWeaponType,t,this.game,i,e)):console.warn(`Tile ${this.tile.x},${this.tile.y} doesn't exist`)}}class ActivateSuperWeaponActionFactory{constructor(e){this.game=e}create(){return new ActivateSuperWeaponAction(this.game)}}class PingLocationEvent{constructor(e,t){this.tile=e,this.player=t,this.type=EventType.PingLocation}}class PingLocationAction extends Action{constructor(e){super(ActionType.PingLocation),this.game=e}unserialize(e){let t=new DataStream(e);this.tile={x:t.readUint16(),y:t.readUint16()}}serialize(){let e=new DataStream(4);return e.writeUint16(this.tile.x),e.writeUint16(this.tile.y),e.toUint8Array()}print(){return`Ping location at tile (${this.tile.x}, ${this.tile.y})`}process(){var e=this.player,t=this.game.map.tiles.getByMapCoords(this.tile.x,this.tile.y);if(t){this.game.events.dispatch(new PingLocationEvent(t,e));for(var i of[e,...this.game.alliances.getAllies(e)])this.game.events.dispatch(new RadarEvent(i,RadarEventType.GenericNonCombat,t))}else console.warn(`Tile ${this.tile.x},${this.tile.y} doesn't exist`)}}class PingLocationActionFactory{constructor(e){this.game=e}create(){return new PingLocationAction(this.game)}}class PlayerResignedEvent{constructor(e,t){this.target=e,this.assetsRedistributed=t,this.type=EventType.PlayerResigned}}class ObserveGameAction extends Action{constructor(e){super(ActionType.ObserveGame),this.game=e}process(){let e=this.player;var t;this.game.removeAllPlayerAssets(e),!e.isCombatant()||e.defeated||e.isObserver||(e.resigned=!0,e.defeated=!0,e.isObserver=!0,this.game.events.dispatch(new PlayerResignedEvent(e)),this.game.events.dispatch(new PlayerDefeatedEvent(e)),this.game.mapShroudTrait.getPlayerShroud(e)?.revealAll(),t=e.radarTrait.isDisabled(),e.radarTrait.setDisabled(!1),t&&this.game.events.dispatch(new RadarOnOffEvent(e,!0)))}}class ObserveGameActionFactory{constructor(e){this.game=e}create(){return new ObserveGameAction(this.game)}}class ResignGameAction extends Action{constructor(e,t){super(ActionType.ResignGame),this.game=e,this.localPlayerName=t}process(){if(this.localPlayerName!==this.player.name){let e=this.player;var t=this.game.redistributeAllPlayerAssets(e);this.game.removeAllPlayerAssets(e),e.isCombatant()&&(e.resigned=!0,this.game.events.dispatch(new PlayerResignedEvent(e,t)))}}}class ResignGameActionFactory{constructor(e,t){this.game=e,this.localPlayerName=t}create(){return new ResignGameAction(this.game,this.localPlayerName)}}!function(e){e[e.SetGlobalDebugText=0]="SetGlobalDebugText",e[e.SetUnitDebugText=1]="SetUnitDebugText"}(DebugCommandType=DebugCommandType||{});class DebugCommand{constructor(e,t){this.type=e,this.params=t}}class DebugAction extends Action{constructor(e){super(ActionType.DebugCommand),this.game=e}unserialize(e){let t=new DataStream(e);e=t.readUint8();e===DebugCommandType.SetUnitDebugText?this.command=new DebugCommand(e,{unitId:t.readUint32(),label:t.readCString()||void 0}):e===DebugCommandType.SetGlobalDebugText?this.command=new DebugCommand(e,{text:t.readCString()}):console.warn(`Debug command ${e} not implemented`)}serialize(){let e=new DataStream;if(e.writeUint8(this.command.type),this.command.type===DebugCommandType.SetUnitDebugText){var t=this.command.params;e.writeUint32(t.unitId),e.writeCString(t.label||"")}else{if(this.command.type!==DebugCommandType.SetGlobalDebugText)throw new Error(`Debug command ${this.command.type} not implemented`);t=this.command.params;e.writeCString(t.text)}return e.toUint8Array()}process(){if(this.command.type===DebugCommandType.SetUnitDebugText){var{unitId:t,label:i}=this.command.params;if(this.game.getWorld().hasObjectId(t)){let e=this.game.getObjectById(t);e.isTechno()&&(e.debugLabel=i)}}else this.command.type===DebugCommandType.SetGlobalDebugText?(i=this.command.params["text"],this.game.debugText.value=i):console.warn(`Debug command ${this.command.type} not implemented`)}}class DebugActionFactory{constructor(e){this.game=e}create(){return new DebugAction(this.game)}}class ActionFactoryReg{register(e,t,i){var r=new OrderActionContext;e.registerFactory(ActionType.NoAction,new NoActionFactory),e.registerFactory(ActionType.PlaceBuilding,new PlaceBuildingActionFactory(t)),e.registerFactory(ActionType.SellObject,new SellObjectActionFactory(t)),e.registerFactory(ActionType.ToggleRepair,new ToggleRepairActionFactory(t)),e.registerFactory(ActionType.SelectUnits,new SelectUnitsActionFactory(t,r)),e.registerFactory(ActionType.OrderUnits,new OrderUnitsActionFactory(t,t.map,r)),e.registerFactory(ActionType.UpdateQueue,new UpdateQueueActionFactory(t)),e.registerFactory(ActionType.ToggleAlliance,new ToggleAllianceActionFactory(t)),e.registerFactory(ActionType.ActivateSuperWeapon,new ActivateSuperWeaponActionFactory(t)),e.registerFactory(ActionType.PingLocation,new PingLocationActionFactory(t)),e.registerFactory(ActionType.DropPlayer,new DropPlayerActionFactory(t,i)),e.registerFactory(ActionType.ObserveGame,new ObserveGameActionFactory(t)),e.registerFactory(ActionType.ResignGame,new ResignGameActionFactory(t,i)),e.registerFactory(ActionType.DebugCommand,new DebugActionFactory(t))}}class SharedDetectDisguiseTrait_SharedDetectDisguiseTrait{constructor(){this.detectors=new Set}[NotifySpawn_NotifySpawn.onSpawn](e,t){this.isGlobalDetector(e)&&(this.detectors.add(e),this.updateAroundDetector(e,t)),this.isDisguisable(e)&&this.detect(e,t)}[NotifyUnspawn_NotifyUnspawn.onUnspawn](e,t){e.isTechno()&&(this.isGlobalDetector(e)&&(this.detectors.delete(e),this.updateAroundDetector(e,t)),this.isDisguisable(e)&&this.undetect(e,t))}[NotifyOwnerChange_NotifyOwnerChange.onChange](e,t,i){this.isGlobalDetector(e)&&this.updateAroundDetector(e,i),this.isDisguisable(e)&&(this.undetect(e,i),this.detect(e,i))}[NotifyTileChange.onTileChange](e,t,i){this.isGlobalDetector(e)&&(this.updateAroundDetector(e,t,i),this.updateAroundDetector(e,t)),this.isDisguisable(e)&&(this.undetect(e,t),this.detect(e,t))}[NotifyPower.onPowerLow](t,e){var i=[...this.detectors].filter(e=>e.owner===t&&e.isBuilding()&&e.poweredTrait&&!e.poweredTrait.isPoweredOn());this.updateAroundDetectors(i,e)}[NotifyPower.onPowerRestore](t,e){var i=[...this.detectors].filter(e=>e.owner===t&&e.isBuilding()&&e.poweredTrait);this.updateAroundDetectors(i,e)}[NotifyPower.onPowerChange](e,t){}updateAroundDetectors(e,t){let i=new Set;for(var r of e)for(var s of this.findTechnosAroundDetector(r,t,r.tile))i.add(s);for(var a of i)this.isDisguisable(a)&&(this.undetect(a,t),this.detect(a,t))}updateAroundDetector(e,t,i=e.tile){var r;for(r of this.findTechnosAroundDetector(e,t,i))this.isDisguisable(r)&&(this.undetect(r,t),this.detect(r,t))}findTechnosAroundDetector(e,t,i){var r=e.getFoundation(),r=Math.max(r.width,r.height),e=e.rules.detectDisguiseRange+r,r=new Vector2(i.rx,i.ry).addScalar(-e),e=new Vector2(i.rx,i.ry).addScalar(e);return t.map.technosByTile.queryRange(new Box2(r,e))}detect(e,t){let i=new Set,r=new RangeHelper(t.map.tileOccupation);for(var s of this.detectors)if(!t.areFriendly(s,e)){var a=s.owner,n=s.rules.detectDisguiseRange;if(!i.has(a))if(!(s.isBuilding()&&s.poweredTrait&&!s.poweredTrait.isPoweredOn())&&r.tileDistance(e,s.tile)<=n)for(var o of[a,...t.alliances.getAllies(a)])i.add(o)}for(var l of i)l.sharedDetectDisguiseTrait?.add(e)}undetect(e,t){for(var i of t.getCombatants())i.sharedDetectDisguiseTrait?.delete(e)}isGlobalDetector(e){return!(!e.isTechno()||!e.rules.detectDisguiseRange)}isDisguisable(e){return!(!e.isInfantry()&&!e.isVehicle()||!e.disguiseTrait)}}class SharedDetectCloakTrait{constructor(){this.detectors=new Set}[NotifySpawn_NotifySpawn.onSpawn](e,t){this.isGlobalDetector(e)&&(this.detectors.add(e),this.updateAroundDetector(e,t)),this.isCloakable(e)&&this.detect(e,t)}[NotifyUnspawn_NotifyUnspawn.onUnspawn](e,t){e.isTechno()&&this.isGlobalDetector(e)&&this.detectors.delete(e)}[NotifyOwnerChange_NotifyOwnerChange.onChange](e,t,i){this.isGlobalDetector(e)&&this.updateAroundDetector(e,i),this.isCloakable(e)&&this.detect(e,i)}[NotifyTileChange.onTileChange](e,t,i){this.isGlobalDetector(e)&&this.updateAroundDetector(e,t),this.isCloakable(e)&&this.detect(e,t)}[NotifyObjectTraitAdd.onAdd](e,t,i){e.isTechno()&&(t instanceof CloakableTrait?this.isCloakable(e)&&this.detect(e,i):t instanceof SensorsTrait&&this.isGlobalDetector(e)&&this.updateAroundDetector(e,i))}[NotifyPower.onPowerLow](e,t){}[NotifyPower.onPowerRestore](t,e){var i=[...this.detectors].filter(e=>e.owner===t&&e.isBuilding()&&e.poweredTrait);this.updateAroundDetectors(i,e)}[NotifyPower.onPowerChange](e,t){}[NotifyTick.onTick](e){for(var t of e.getCombatants()){var i;for(i of t.getOwnedObjects())i.cloakableTrait&&!i.cloakableTrait.isCloaked()&&this.detect(i,e)}}updateAroundDetectors(e,t){let i=new Set;for(var r of e)for(var s of this.findTechnosAroundDetector(r,t))i.add(s);for(var a of i)this.isCloakable(a)&&this.detect(a,t)}updateAroundDetector(e,t){var i;for(i of this.findTechnosAroundDetector(e,t))this.isCloakable(i)&&this.detect(i,t)}findTechnosAroundDetector(e,t){var i=e.getFoundation(),r=Math.max(i.width,i.height),i=e.rules.sensorsSight+r,r=new Vector2(e.tile.rx,e.tile.ry).addScalar(-i),i=new Vector2(e.tile.rx,e.tile.ry).addScalar(i);return t.map.technosByTile.queryRange(new Box2(r,i))}detect(e,t){let i=new RangeHelper(t.map.tileOccupation);for(var r of this.detectors)if(!t.areFriendly(r,e)){var s=r.rules.sensorsSight;if(!(r.isBuilding()&&r.poweredTrait&&!r.poweredTrait.isPoweredOn())&&i.tileDistance(e,r.tile)<=s){s=e.cloakableTrait?.isCloaked();if(e.cloakableTrait.uncloak(t),s)for(var a of[r.owner,...t.alliances.getAllies(r.owner)])t.traits.get(RadarTrait_RadarTrait).addEventForPlayer(RadarEventType.GenericNonCombat,a,e.tile,t);break}}}isGlobalDetector(e){return!(!e.isTechno()||!e.sensorsTrait&&!e.rules.sensorArray||!e.rules.sensorsSight)}isCloakable(e){return e.isTechno()&&!!e.cloakableTrait}}class StalemateDetectEvent{constructor(){this.type=EventType.StalemateDetect}}class StalemateDetectTrait{constructor(){this.stale=!1,this.allPlayersCredits=new Map,this.resetCountdown()}isStale(){return this.stale}getCountdownTicks(){return this.countdownTicks}resetCountdown(){this.countdownTicks=Math.floor(60*StalemateDetectTrait.graceMinutes*GameSpeed.BASE_TICKS_PER_SECOND)}clearStale(){this.stale=!1,this.resetCountdown()}[NotifyTick.onTick](e){0<this.countdownTicks?this.countdownTicks--:this.stale||(this.stale=!0,this.resetCountdown(),e.events.dispatch(new StalemateDetectEvent));for(var t of e.getCombatants()){var i=this.allPlayersCredits.get(t);i!==t.credits&&(this.allPlayersCredits.set(t,t.credits),t.credits>(i??0)&&t.production.hasAnyFactory()&&this.clearStale())}}[NotifyProduceUnit.onProduce](){this.clearStale()}[NotifyPlaceBuilding.onPlace](e){e.wallTrait||this.clearStale()}[NotifyDestroy_NotifyDestroy.onDestroy](e,t,i){!e.isBuilding()||e.owner.isNeutral||e.wallTrait||e.rules.insignificant||e.owner.defeated&&this.stale||i?.obj&&t.areFriendly(e,i.obj)||this.clearStale()}[NotifyOwnerChange_NotifyOwnerChange.onChange](e,t,i){e.isBuilding()&&!t.isNeutral&&(i.alliances.areAllied(e.owner,t)||this.clearStale())}}StalemateDetectTrait.graceMinutes=10;class GameOptSanitizer{static sanitize(e,t){t=t.mpDialogSettings;e.credits=Math.floor(clamp(e.credits,t.minMoney,t.maxMoney)),e.gameSpeed=Math.floor(clamp(e.gameSpeed,0,6)),e.unitCount=Math.floor(clamp(e.unitCount,t.minUnitCount,t.maxUnitCount))}}class GameOptRandomGen{static factory(e,t){return new this(Prng.factory(e,t))}constructor(e){this.prng=e}generateColors(e){let t=[...e.humanPlayers,...e.aiPlayers].filter(isNotNullOrUndefined),i=t.map(e=>e.colorId).filter(e=>e!==RANDOM_COLOR_ID);e=mpAllowedColors.length;let r=new Array(e).fill(0).map((e,t)=>t).filter(e=>!i.includes(e)),s=new Map;return t.forEach(e=>{if(e.countryId!==OBS_COUNTRY_ID&&e.colorId===RANDOM_COLOR_ID){if(r.length<1)throw new Error("Out of available colors to choose from");var t=this.prng.generateRandomInt(0,r.length-1);s.set(e,r[t]),r.splice(t,1)}}),s}generateCountries(e,t){let i=t.getMultiplayerCountries().length,r=[...e.humanPlayers,...e.aiPlayers].filter(isNotNullOrUndefined),s=new Map;return r.forEach(e=>{e.countryId===RANDOM_COUNTRY_ID&&s.set(e,this.prng.generateRandomInt(0,i-1))}),s}generateStartLocations(i,r){let e=[...i.humanPlayers,...i.aiPlayers].filter(isNotNullOrUndefined),t=e.filter(e=>e.startPos!==RANDOM_START_POS).map(e=>e.startPos),s=[...r.keys()].filter(e=>!t.includes(e)),a=[];for(;s.length;){var n=s.length?this.prng.generateRandomInt(0,s.length-1):0;a.push(...s.splice(n,1))}if(a.unshift(...t),3<=a.length)for(var o of[1,2])if(!(t.length-1>=o)){let e=a.map(e=>r[e]),t=this.findFarthestPointFrom(e.slice(0,o),e.slice(o));var l=e.findIndex(e=>e.x===t.x&&e.y===t.y);a.splice(o,0,...a.splice(l,1))}if(4<=a.length)if(t.length-1<3){let e=a.map(e=>r[e]),t=this.findFarthestPointFrom(e.slice(2,3),e.slice(3));i=e.findIndex(e=>e.x===t.x&&e.y===t.y);a.splice(3,0,...a.splice(i,1))}a.splice(0,t.length);let h=new Map,c=-1;return e.forEach(e=>{if(e.countryId!==OBS_COUNTRY_ID&&e.startPos===RANDOM_START_POS){if(c>=a.length-1)throw new RangeError("Map has fewer starting locations than players");h.set(e,a[++c])}}),h}findFarthestPointFrom(e,t){let r=e.map(e=>new Vector2(e.x,e.y)),s,a=0;if(!t.length)throw new Error("Search array must have at least one element");for(var n of t){let i=new Vector2(n.x,n.y);var o=r.reduce((e,t)=>e+i.distanceTo(t),0);o>=a&&(s=n,a=o)}return s}}class MapLightingTrait{get onChange(){return this._onChange.asEvent()}constructor(e,t){this.mapLighting=new MapLighting,this._onChange=new EventDispatcher,this.ambientChangeRate=e.ambientChangeRate,this.ambientChangeStep=e.ambientChangeStep,t&&this.mapLighting.copy(t)}setAmbientChangeRate(e){this.ambientChangeRate=e}setAmbientChangeStep(e){this.ambientChangeStep=e}setTargetAmbientIntensity(e){this.targetAmbient=e}getAmbient(){return this.mapLighting}[NotifyTick.onTick](){var e;void 0!==this.targetAmbient&&(this.ambientUpdateTicks??(this.ambientUpdateTicks=Math.floor(60*GameSpeed.BASE_TICKS_PER_SECOND*this.ambientChangeRate)),this.ambientUpdateTicks<=0?(this.ambientUpdateTicks=void 0,e=this.mapLighting.ambient,(e=this.targetAmbient-e)?(e=Math.sign(e)*Math.min(this.ambientChangeStep,Math.abs(e)),this.mapLighting.ambient+=e,this._onChange.dispatch(this,this.mapLighting)):this.targetAmbient=void 0):this.ambientUpdateTicks--)}}class Ai{constructor(e){this.ini=e}getIni(){return this.ini}}var _Bot_debugMode,BotState,__classPrivateFieldGet=function(e,t,i,r){if("a"===i&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?r:"a"===i?r.call(e):r?r.value:t.get(e)},__classPrivateFieldSet=function(e,t,i,r,s){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!s)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!s:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?s.call(e,i):s?s.value=i:t.set(e,i),i};class Bot{get game(){return this.context?.game}get player(){return this.context?.player}get gameApi(){return this.context?.game}get actionsApi(){return this.context?.player.actions}get productionApi(){return this.context?.player.production}get logger(){return this.context?.logger}constructor(e,t){this.name=e,this.country=t,_Bot_debugMode.set(this,!1)}setContext(e){this.context=e,this.context.logger.setDebugLevel(__classPrivateFieldGet(this,_Bot_debugMode,"f"))}setGameApi(e){}setActionsApi(e){}setProductionApi(e){}setLogger(e){}setDebugMode(e){return __classPrivateFieldSet(this,_Bot_debugMode,e,"f"),this.context?.logger.setDebugLevel(e),this}getDebugMode(){return __classPrivateFieldGet(this,_Bot_debugMode,"f")}onGameInit(e){}onGameStart(e){}onGameTick(e){}onGameEvent(e,t){}}_Bot_debugMode=new WeakMap,function(e){e[e.Initial=0]="Initial",e[e.Deployed=1]="Deployed",e[e.Attacking=2]="Attacking",e[e.Defeated=3]="Defeated"}(BotState=BotState||{});class DummyBot extends Bot{constructor(){super(...arguments),this.botState=BotState.Initial}onGameStart(t){var e=t.getTickRate();this.tickRatio=Math.ceil(e/5),this.enemyPlayers=t.getPlayers().filter(e=>e!==this.name&&!t.areAlliedPlayers(this.name,e))}onGameTick(e){if(e.getCurrentTick()%this.tickRatio==0)switch(this.botState){case BotState.Initial:{const i=e.getGeneralRules().baseUnit;if(e.getVisibleUnits(this.name,"self",e=>e.constructionYard).length){this.botState=BotState.Deployed;break}var t=e.getVisibleUnits(this.name,"self",e=>i.includes(e.name));t.length&&this.actionsApi.orderUnits([t[0]],OrderType.DeploySelected);break}case BotState.Deployed:break;case BotState.Attacking:e.getVisibleUnits(this.name,"self",e=>e.isSelectableCombatant).length||(this.botState=BotState.Defeated,this.actionsApi.quitGame())}}}class BotFactory{constructor(e){this.botsLib=e}create(e){if(!e.isAi)throw new Error(`Player "${e.name}" is not an AI`);switch(e.aiDifficulty){case AiDifficulty.Easy:return new DummyBot(e.name,e.country.name);case AiDifficulty.Medium:if(this.botsLib.SupalosaBot)return new this.botsLib.SupalosaBot(e.name,e.country.name);default:throw new Error(`Unsupported AI difficulty "${e.aiDifficulty}"`)}}}class ActionQueue{constructor(){this.actions=[]}push(...e){this.actions.push(...e)}getLast(){return this.actions[this.actions.length-1]}dequeueAll(){var e=[...this.actions];return this.actions.length=0,e}dequeueLast(){return this.actions.pop()}clear(){this.actions.length=0}}var ActionsApi_classPrivateFieldSet=function(e,t,i,r,s){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!s)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!s:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?s.call(e,i):s?s.value=i:t.set(e,i),i},ActionsApi_classPrivateFieldGet=function(e,t,i,r){if("a"===i&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?r:"a"===i?r.call(e):r?r.value:t.get(e)};class ActionsApi{constructor(e,t,i,r,s){_ActionsApi_instances.add(this),_ActionsApi_actionFactory.set(this,void 0),_ActionsApi_actionQueue.set(this,void 0),_ActionsApi_game.set(this,void 0),_ActionsApi_bot.set(this,void 0),_ActionsApi_chatApi.set(this,void 0),ActionsApi_classPrivateFieldSet(this,_ActionsApi_actionFactory,t,"f"),ActionsApi_classPrivateFieldSet(this,_ActionsApi_actionQueue,i,"f"),ActionsApi_classPrivateFieldSet(this,_ActionsApi_game,e,"f"),ActionsApi_classPrivateFieldSet(this,_ActionsApi_bot,r,"f"),ActionsApi_classPrivateFieldSet(this,_ActionsApi_chatApi,s,"f")}placeBuilding(t,i,r){ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.PlaceBuilding,e=>{e.buildingRules=ActionsApi_classPrivateFieldGet(this,_ActionsApi_game,"f").rules.getBuilding(t),e.tile={x:i,y:r}})}sellObject(t){ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.SellObject,e=>{e.objectId=t})}sellBuilding(e){this.sellObject(e)}toggleRepairWrench(t){ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.ToggleRepair,e=>{e.buildingId=t})}toggleAlliance(t,i){ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.ToggleAlliance,e=>{e.toPlayer=ActionsApi_classPrivateFieldGet(this,_ActionsApi_game,"f").getPlayerByName(t),e.toggle=i})}pauseProduction(t){ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.UpdateQueue,e=>{e.queueType=t,e.updateType=UpdateType.Pause})}resumeProduction(t){ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.UpdateQueue,e=>{e.queueType=t,e.updateType=UpdateType.Resume})}queueForProduction(t,e,i,r){let s=ActionsApi_classPrivateFieldGet(this,_ActionsApi_game,"f").rules.getObject(e,i);ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.UpdateQueue,e=>{e.queueType=t,e.updateType=UpdateType.Add,e.item=s,e.quantity=r})}unqueueFromProduction(t,e,i,r){let s=ActionsApi_classPrivateFieldGet(this,_ActionsApi_game,"f").rules.getObject(e,i);ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.UpdateQueue,e=>{e.queueType=t,e.updateType=UpdateType.Cancel,e.item=s,e.quantity=r})}activateSuperWeapon(t,i,r){ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.ActivateSuperWeapon,e=>{e.superWeaponType=t,e.tile={x:i.rx,y:i.ry},e.tile2=r?{x:r.rx,y:r.ry}:void 0})}orderUnits(t,i,r,s,a){ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.SelectUnits,e=>{e.unitIds=t});let n;if(r){let e,t;if(s){e=void 0;var o=ActionsApi_classPrivateFieldGet(this,_ActionsApi_game,"f").map.tiles.getByMapCoords(r,s);if(!o)throw new Error(`No tile found at rx,ry=${r},`+s);t=o,a&&(e=ActionsApi_classPrivateFieldGet(this,_ActionsApi_game,"f").map.tileOccupation.getBridgeOnTile(o))}else{if(!ActionsApi_classPrivateFieldGet(this,_ActionsApi_game,"f").getWorld().hasObjectId(r))return;e=ActionsApi_classPrivateFieldGet(this,_ActionsApi_game,"f").getObjectById(r),t=e.tile}n=ActionsApi_classPrivateFieldGet(this,_ActionsApi_game,"f").createTarget(e,t)}ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.OrderUnits,e=>{e.orderType=i,e.target=n})}sayAll(e){ActionsApi_classPrivateFieldGet(this,_ActionsApi_chatApi,"f")?.sayAll(ActionsApi_classPrivateFieldGet(this,_ActionsApi_bot,"f").name,e)}setGlobalDebugText(t){ActionsApi_classPrivateFieldGet(this,_ActionsApi_bot,"f").getDebugMode()&&ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.DebugCommand,e=>{e.command=new DebugCommand(DebugCommandType.SetGlobalDebugText,{text:t||""})})}setUnitDebugText(t,i){ActionsApi_classPrivateFieldGet(this,_ActionsApi_bot,"f").getDebugMode()&&ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.DebugCommand,e=>{e.command=new DebugCommand(DebugCommandType.SetUnitDebugText,{unitId:t,label:i})})}quitGame(){ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.ResignGame)}}var ApiEventType,_ActionsApi_actionFactory=new WeakMap,_ActionsApi_actionQueue=new WeakMap,_ActionsApi_game=new WeakMap,_ActionsApi_bot=new WeakMap,_ActionsApi_chatApi=new WeakMap,_ActionsApi_instances=new WeakSet,_ActionsApi_pushAction=function(e,t){let i=ActionsApi_classPrivateFieldGet(this,_ActionsApi_actionFactory,"f").create(e);i.player=ActionsApi_classPrivateFieldGet(this,_ActionsApi_game,"f").getPlayerByName(ActionsApi_classPrivateFieldGet(this,_ActionsApi_bot,"f").name),t?.(i),ActionsApi_classPrivateFieldGet(this,_ActionsApi_actionQueue,"f").push(i)},EventsApi_classPrivateFieldSet=function(e,t,i,r,s){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!s)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!s:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?s.call(e,i):s?s.value=i:t.set(e,i),i},EventsApi_classPrivateFieldGet=function(e,t,i,r){if("a"===i&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?r:"a"===i?r.call(e):r?r.value:t.get(e)};!function(e){e[e.ObjectOwnerChange=0]="ObjectOwnerChange",e[e.ObjectSpawn=1]="ObjectSpawn",e[e.ObjectUnspawn=2]="ObjectUnspawn",e[e.ObjectDestroy=3]="ObjectDestroy"}(ApiEventType=ApiEventType||{});class EventsApi{constructor(e){_EventsApi_instances.add(this),_EventsApi_eventBus.set(this,void 0),_EventsApi_listenerDisposers.set(this,[]),EventsApi_classPrivateFieldSet(this,_EventsApi_eventBus,e,"f")}subscribe(e,t){let i=void 0,r;r="function"==typeof e?e:(i=e,t);t=EventsApi_classPrivateFieldGet(this,_EventsApi_eventBus,"f").subscribe(e=>{e=EventsApi_classPrivateFieldGet(this,_EventsApi_instances,"m",_EventsApi_translateGameEvent).call(this,e);!e||void 0!==i&&i!==e.type||r(e)});return EventsApi_classPrivateFieldGet(this,_EventsApi_listenerDisposers,"f").push(t),t}dispose(){for(var e of EventsApi_classPrivateFieldGet(this,_EventsApi_listenerDisposers,"f"))e();EventsApi_classPrivateFieldGet(this,_EventsApi_listenerDisposers,"f").length=0}}var _EventsApi_eventBus=new WeakMap,_EventsApi_listenerDisposers=new WeakMap,_EventsApi_instances=new WeakSet,_EventsApi_translateGameEvent=function(t){switch(t.type){case EventType.ObjectOwnerChange:return{type:ApiEventType.ObjectOwnerChange,prevOwnerName:t.prevOwner.name,newOwnerName:t.target.owner.name,target:t.target.id};case EventType.ObjectSpawn:return{type:ApiEventType.ObjectSpawn,target:t.gameObject.id};case EventType.ObjectUnspawn:return{type:ApiEventType.ObjectUnspawn,target:t.gameObject.id};case EventType.ObjectDestroy:{let e=t;return e.target.isProjectile()?void 0:{type:ApiEventType.ObjectDestroy,target:e.target.id,attackerInfo:e.attackerInfo?{playerName:e.attackerInfo.player.name,objId:e.attackerInfo.obj?.id,weaponName:e.attackerInfo.weapon?.rules.name}:void 0}}default:return}},MapApi_classPrivateFieldSet=function(e,t,i,r,s){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!s)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!s:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?s.call(e,i):s?s.value=i:t.set(e,i),i},MapApi_classPrivateFieldGet=function(e,t,i,r){if("a"===i&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?r:"a"===i?r.call(e):r?r.value:t.get(e)};class MapApi{constructor(e){_MapApi_instances.add(this),_MapApi_game.set(this,void 0),_MapApi_map.set(this,void 0),MapApi_classPrivateFieldSet(this,_MapApi_game,e,"f"),MapApi_classPrivateFieldSet(this,_MapApi_map,e.map,"f")}getRealMapSize(){return MapApi_classPrivateFieldGet(this,_MapApi_map,"f").tiles.getMapSize()}getStartingLocations(){return MapApi_classPrivateFieldGet(this,_MapApi_map,"f").startingLocations.map(e=>new Vector2(e.x,e.y))}getTheaterType(){return MapApi_classPrivateFieldGet(this,_MapApi_map,"f").getTheaterType()}getTile(e,t){t=MapApi_classPrivateFieldGet(this,_MapApi_map,"f").tiles.getByMapCoords(e,t);if(t&&MapApi_classPrivateFieldGet(this,_MapApi_map,"f").mapBounds.isWithinBounds(t))return t}getTilesInRect(e,t){let i=t?MapApi_classPrivateFieldGet(this,_MapApi_map,"f").tiles.getInRectangle(e,t):MapApi_classPrivateFieldGet(this,_MapApi_map,"f").tiles.getInRectangle(e);return i.filter(e=>MapApi_classPrivateFieldGet(this,_MapApi_map,"f").mapBounds.isWithinBounds(e))}getObjectsOnTile(e){return MapApi_classPrivateFieldGet(this,_MapApi_map,"f").getObjectsOnTile(e).map(e=>e.id)}hasBridgeOnTile(e){return!!e.onBridgeLandType}hasHighBridgeOnTile(e){return!!MapApi_classPrivateFieldGet(this,_MapApi_map,"f").tileOccupation.getBridgeOnTile(e)?.isHighBridge()}isPassableTile(e,t,i,r){return r=r??t===SpeedType.Foot,0<MapApi_classPrivateFieldGet(this,_MapApi_map,"f").terrain.getPassableSpeed(e,t,r,i)}findPath(e,t,i,r,s){let a=MapApi_classPrivateFieldGet(this,_MapApi_game,"f").map.terrain.computePath(e,t,i.tile,i.onBridge,r.tile,r.onBridge,{bestEffort:s?.bestEffort,excludeTiles:s?.excludeNodes?e=>s.excludeNodes({tile:e.tile,onBridge:!!e.onBridge}):void 0,maxExpandedNodes:s?.maxExpandedNodes});return a.map(e=>({tile:e.tile,onBridge:!!e.onBridge}))}getReachabilityMap(e,t){let i=MapApi_classPrivateFieldGet(this,_MapApi_game,"f").map.terrain.getIslandIdMap(e,t);return{isReachable(e,t){e=this.getRegionId(e),t=this.getRegionId(t);return void 0!==e&&e===t},getRegionId(e){return i.get(e.tile,e.onBridge)}}}isVisibleTile(e,t,i=0){var r=MapApi_classPrivateFieldGet(this,_MapApi_game,"f").getPlayerByName(t);if(!r)throw new Error(`Player "${t}" doesn't exist`);return!MapApi_classPrivateFieldGet(this,_MapApi_game,"f").mapShroudTrait.getPlayerShroud(r)?.isShrouded(e,i)}getTileResourceData(e){e=MapApi_classPrivateFieldGet(this,_MapApi_map,"f").getObjectsOnTile(e).find(e=>e.isOverlay()&&e.isTiberium()||e.isTerrain()&&e.rules.spawnsTiberium);return e?MapApi_classPrivateFieldGet(this,_MapApi_instances,"m",_MapApi_getTileResourceDataFromObject).call(this,e):void 0}getAllTilesResourceData(){var e;let t=[];for(e of MapApi_classPrivateFieldGet(this,_MapApi_game,"f").getWorld().getAllObjects()){var i=MapApi_classPrivateFieldGet(this,_MapApi_instances,"m",_MapApi_getTileResourceDataFromObject).call(this,e);i&&t.push(i)}return t}}var _MapApi_game=new WeakMap,_MapApi_map=new WeakMap,_MapApi_instances=new WeakSet,_MapApi_getTileResourceDataFromObject=function(t){let i;if(t.isOverlay()&&t.isTiberium()){let e=t.traits.get(TiberiumTrait);var r=e.getTiberiumType(),s=e.getBailCount();i={tile:t.tile,ore:r!==TiberiumType.Gems?s:0,gems:r===TiberiumType.Gems?s:0,spawnsOre:!1}}else t.isTerrain()&&t.rules.spawnsTiberium&&(i={tile:t.tile,ore:0,gems:0,spawnsOre:!0});return i},RulesApi_classPrivateFieldGet=function(e,t,i,r){if("a"===i&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?r:"a"===i?r.call(e):r?r.value:t.get(e)},RulesApi_classPrivateFieldSet=function(e,t,i,r,s){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!s)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!s:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?s.call(e,i):s?s.value=i:t.set(e,i),i};class RulesApi{get allObjectRules(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").allObjectRules}get buildingRules(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").buildingRules}get infantryRules(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").infantryRules}get vehicleRules(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").vehicleRules}get aircraftRules(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").aircraftRules}get terrainRules(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").terrainRules}get overlayRules(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").overlayRules}get countryRules(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").countryRules}get general(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").general}get ai(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").ai}get crateRules(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").crateRules}get combatDamage(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").combatDamage}get radiation(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").radiation}constructor(e){_RulesApi_rules.set(this,void 0),RulesApi_classPrivateFieldSet(this,_RulesApi_rules,e,"f")}hasObject(e,t){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").hasObject(e,t)}getObject(e,t){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").getObject(e,t)}getBuilding(e){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").getBuilding(e)}getWeapon(e){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").getWeapon(e)}getWarhead(e){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").getWarhead(e)}getProjectile(e){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").getProjectile(e)}getOverlayName(e){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").getOverlayName(e)}getOverlayId(e){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").getOverlayId(e)}getOverlay(e){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").getOverlay(e)}getCountry(e){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").getCountry(e)}getMultiplayerCountries(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").getMultiplayerCountries()}getIni(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").getIni()}}var _RulesApi_rules=new WeakMap,GameApi_classPrivateFieldSet=function(e,t,i,r,s){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!s)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!s:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?s.call(e,i):s?s.value=i:t.set(e,i),i},GameApi_classPrivateFieldGet=function(e,t,i,r){if("a"===i&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?r:"a"===i?r.call(e):r?r.value:t.get(e)};class GameApi{get mapApi(){return this.map}get rulesApi(){return this.rules}constructor(e,t){_GameApi_instances.add(this),_GameApi_game.set(this,void 0),_GameApi_useInternalRng.set(this,void 0),GameApi_classPrivateFieldSet(this,_GameApi_game,e,"f"),GameApi_classPrivateFieldSet(this,_GameApi_useInternalRng,t,"f"),this.map=new MapApi(e),this.rules=new RulesApi(e.rules)}isPlayerDefeated(e){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getPlayerByName(e).defeated}areAlliedPlayers(e,t){var i=GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getPlayerByName(e);if(!i)throw new Error(`Player "${e}" doesn't exist`);e=GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getPlayerByName(t);if(!e)throw new Error(`Player "${t}" doesn't exist`);return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").alliances.areAllied(i,e)}canPlaceBuilding(e,t,i,r){var s=GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getPlayerByName(e);if(!s)throw new Error(`Player "${e}" doesn't exist`);return(r=r??{}).ignoreAdjacent??(r.ignoreAdjacent=this.rules.getBuilding(t).constructionYard),GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getConstructionWorker(s).canPlaceAt(t,i,{normalizedTile:!0,...r})}getBuildingPlacementData(e){e=GameApi_classPrivateFieldGet(this,_GameApi_game,"f").art.getObject(e,ObjectType.Building);return{foundation:e.foundation,foundationCenter:e.foundationCenter}}getPlayers(){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getNonNeutralPlayers().map(e=>e.name)}getPlayerData(e){let t=GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getPlayerByName(e);if(!t)throw new Error(`Player "${e}" doesn't exist`);return{name:t.name,country:t.country,startLocation:this.map.getStartingLocations()[t.startLocation??0],isObserver:t.isObserver,isAi:t.isAi,isCombatant:t.isCombatant(),credits:t.credits,power:{total:t.powerTrait?.power??0,drain:t.powerTrait?.drain??0,isLowPower:t.powerTrait?.level===PowerLevel.Low},radarDisabled:!!t.radarTrait?.isDisabled()}}getAllTerrainObjects(){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getWorld().getAllObjects().filter(e=>e.isTerrain()).map(e=>e.id)}getAllUnits(t=()=>!0){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getWorld().getAllObjects().filter(e=>e.isTechno()&&t(e.rules)).map(e=>e.id)}getNeutralUnits(t=()=>!0){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getCivilianPlayer().getOwnedObjects().filter(e=>t(e.rules)).map(e=>e.id)}getUnitsInArea(e){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").map.technosByTile.queryRange(e).map(e=>e.id)}getVisibleUnits(e,r,t=()=>!0){const s=GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getPlayerByName(e);if(!s)throw new Error(`Player "${e}" doesn't exist`);if("self"===r)return s.getOwnedObjects().filter(e=>t(e.rules)).map(e=>e.id);let a;if("allied"===r)a=e=>e.owner===s||GameApi_classPrivateFieldGet(this,_GameApi_game,"f").alliances.areAllied(e.owner,s);else{if("hostile"!==r&&"enemy"!==r)throw new Error("Unexpected type "+r);{let i=GameApi_classPrivateFieldGet(this,_GameApi_game,"f").mapShroudTrait.getPlayerShroud(s);a=t=>GameApi_classPrivateFieldGet(this,_GameApi_game,"f").map.tileOccupation.calculateTilesForGameObject(t.tile,t).some(e=>!i?.isShrouded(e,t.tileElevation))&&t.owner!==s&&!GameApi_classPrivateFieldGet(this,_GameApi_game,"f").alliances.areAllied(t.owner,s)&&("enemy"!==r||t.owner.isCombatant())}}return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getWorld().getAllObjects().filter(e=>e.isTechno()&&!e.isDestroyed&&a(e)&&t(e.rules)).map(e=>e.id)}getGameObjectData(t){if(GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getWorld().hasObjectId(t)){let e=GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getObjectById(t);return{id:e.id,type:e.type,name:e.name,rules:e.rules,tile:e.tile,tileElevation:e.tileElevation,worldPosition:e.position.worldPosition.clone(),foundation:e.getFoundation(),hitPoints:e.healthTrait?.getHitPoints(),maxHitPoints:e.healthTrait?.maxHitPoints,owner:e.isTechno()?e.owner.name:void 0}}}getUnitData(t){var i=this.getGameObjectData(t);if(i){let e=GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getObjectById(t);if(!e.isTechno())throw new Error(`Game object with id ${t} is not a Techno type`);return{...i,owner:e.owner.name,sight:e.sight,veteranLevel:e.veteranLevel,guardMode:e.guardMode,purchaseValue:e.purchaseValue,primaryWeapon:e.primaryWeapon?GameApi_classPrivateFieldGet(this,_GameApi_instances,"m",_GameApi_getWeaponData).call(this,e.primaryWeapon):void 0,secondaryWeapon:e.secondaryWeapon?GameApi_classPrivateFieldGet(this,_GameApi_instances,"m",_GameApi_getWeaponData).call(this,e.secondaryWeapon):void 0,deathWeapon:e.armedTrait?.deathWeapon?GameApi_classPrivateFieldGet(this,_GameApi_instances,"m",_GameApi_getWeaponData).call(this,e.armedTrait.deathWeapon):void 0,attackState:e.attackTrait?.attackState,direction:e.direction,onBridge:e.isInfantry()||e.isVehicle()?e.onBridge:void 0,zone:e.isUnit()?e.zone:void 0,buildStatus:e.isBuilding()?e.buildStatus:void 0,factory:e.isBuilding()&&e.factoryTrait?{deliveringUnit:e.factoryTrait.deliveringUnit?.id,status:e.factoryTrait.status}:void 0,rallyPoint:e.isBuilding()?e.rallyTrait?.getRallyPoint():void 0,isPoweredOn:e.isBuilding()&&e.poweredTrait?.isPoweredOn(),hasWrenchRepair:e.isBuilding()&&!e.autoRepairTrait.isDisabled(),turretFacing:e.isBuilding()||e.isVehicle()?e.turretTrait?.facing:void 0,turretNo:e.isVehicle()?e.turretNo:void 0,garrisonUnitCount:e.isBuilding()?e.garrisonTrait?.units.length:void 0,garrisonUnitsMax:e.isBuilding()?e.garrisonTrait?.maxOccupants:void 0,passengerSlotCount:e.isVehicle()?e.transportTrait?.getOccupiedCapacity():void 0,passengerSlotMax:e.isVehicle()?e.transportTrait?.getMaxCapacity():void 0,isIdle:!e.unitOrderTrait.hasTasks(),canMove:e.isUnit()?!e.moveTrait.isDisabled():void 0,velocity:e.isUnit()?e.moveTrait.velocity.clone():void 0,stance:e.isInfantry()?e.stance:void 0,harvestedOre:e.isVehicle()?e.harvesterTrait?.ore:void 0,harvestedGems:e.isVehicle()?e.harvesterTrait?.gems:void 0,ammo:e.isAircraft()?e.ammo:void 0,isWarpedOut:e.warpedOutTrait.isActive(),mindControlledBy:e.mindControllableTrait?.getController()?.id,tntTimer:e.tntChargeTrait?.getTicksLeft()}}}getAllSuperWeaponData(){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getCombatants().map(t=>t.superWeaponsTrait.getAll().map(e=>({playerName:t.name,type:e.rules.type,status:e.status,timerSeconds:e.getTimerSeconds()}))).flat()}getGeneralRules(){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").rules.general}getRulesIni(){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").rules.getIni()}getArtIni(){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").art.getIni()}getAiIni(){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").ai.getIni()}generateRandomInt(e,t){if(GameApi_classPrivateFieldGet(this,_GameApi_useInternalRng,"f"))return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").generateRandomInt(e,t);var i=this.generateRandom();return Math.floor(i*(t-e+1))+e}generateRandom(){return GameApi_classPrivateFieldGet(this,_GameApi_useInternalRng,"f")?GameApi_classPrivateFieldGet(this,_GameApi_game,"f").generateRandom():Math.random()}getTickRate(){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").speed.value*GameSpeed.BASE_TICKS_PER_SECOND}getBaseTickRate(){return GameSpeed.BASE_TICKS_PER_SECOND}getCurrentTick(){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").currentTick}getCurrentTime(){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").currentTime/1e3}}function formatTimeDuration(e,t=!1){var i=Math.floor(e/3600);e-=3600*i;var r=Math.floor(e/60),e=e-=60*r;return[...i||!t?[i]:[],pad(r,"00"),pad(e,"00")].join(":")}var _GameApi_game=new WeakMap,_GameApi_useInternalRng=new WeakMap,_GameApi_instances=new WeakSet,_GameApi_getWeaponData=function(e){return{type:e.type,rules:e.rules,projectileRules:e.projectileRules,warheadRules:e.warhead.rules,minRange:e.minRange,maxRange:e.range,speed:e.speed,cooldownTicks:e.getCooldownTicks()}},LoggerApi_classPrivateFieldSet=function(e,t,i,r,s){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!s)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!s:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?s.call(e,i):s?s.value=i:t.set(e,i),i},LoggerApi_classPrivateFieldGet=function(e,t,i,r){if("a"===i&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?r:"a"===i?r.call(e):r?r.value:t.get(e)};class LoggerApi{constructor(e,t){_LoggerApi_instances.add(this),_LoggerApi_logger.set(this,void 0),_LoggerApi_game.set(this,void 0),LoggerApi_classPrivateFieldSet(this,_LoggerApi_logger,e,"f"),LoggerApi_classPrivateFieldSet(this,_LoggerApi_game,t,"f")}setDebugLevel(e){LoggerApi_classPrivateFieldGet(this,_LoggerApi_logger,"f").setLevel(e?AppLogger.DEBUG:AppLogger.WARN)}debug(...e){LoggerApi_classPrivateFieldGet(this,_LoggerApi_logger,"f").debug(LoggerApi_classPrivateFieldGet(this,_LoggerApi_instances,"m",_LoggerApi_getLogPrefix).call(this),...e)}info(...e){LoggerApi_classPrivateFieldGet(this,_LoggerApi_logger,"f").info(LoggerApi_classPrivateFieldGet(this,_LoggerApi_instances,"m",_LoggerApi_getLogPrefix).call(this),...e)}log(...e){LoggerApi_classPrivateFieldGet(this,_LoggerApi_logger,"f").log(LoggerApi_classPrivateFieldGet(this,_LoggerApi_instances,"m",_LoggerApi_getLogPrefix).call(this),...e)}warn(...e){LoggerApi_classPrivateFieldGet(this,_LoggerApi_logger,"f").warn(LoggerApi_classPrivateFieldGet(this,_LoggerApi_instances,"m",_LoggerApi_getLogPrefix).call(this),...e)}error(...e){LoggerApi_classPrivateFieldGet(this,_LoggerApi_logger,"f").error(LoggerApi_classPrivateFieldGet(this,_LoggerApi_instances,"m",_LoggerApi_getLogPrefix).call(this),...e)}time(e){LoggerApi_classPrivateFieldGet(this,_LoggerApi_logger,"f").time(e)}timeEnd(e){LoggerApi_classPrivateFieldGet(this,_LoggerApi_logger,"f").timeEnd(e)}}var _LoggerApi_logger=new WeakMap,_LoggerApi_game=new WeakMap,_LoggerApi_instances=new WeakSet,_LoggerApi_getLogPrefix=function(){return"["+formatTimeDuration(Math.floor(LoggerApi_classPrivateFieldGet(this,_LoggerApi_game,"f").getCurrentTime()))+"]"},ProductionApi_classPrivateFieldSet=function(e,t,i,r,s){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!s)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!s:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?s.call(e,i):s?s.value=i:t.set(e,i),i},ProductionApi_classPrivateFieldGet=function(e,t,i,r){if("a"===i&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?r:"a"===i?r.call(e):r?r.value:t.get(e)};class ProductionApi{constructor(e){_ProductionApi_production.set(this,void 0),ProductionApi_classPrivateFieldSet(this,_ProductionApi_production,e,"f")}isAvailableForProduction(e){return ProductionApi_classPrivateFieldGet(this,_ProductionApi_production,"f").isAvailableForProduction(e)}getAvailableObjects(t){let e=ProductionApi_classPrivateFieldGet(this,_ProductionApi_production,"f").getAvailableObjects();return void 0!==t&&(e=e.filter(e=>this.getQueueTypeForObject(e)===t)),e}getQueueTypeForObject(e){return ProductionApi_classPrivateFieldGet(this,_ProductionApi_production,"f").getQueueTypeForObject(e)}getQueueData(e){let t=ProductionApi_classPrivateFieldGet(this,_ProductionApi_production,"f").getQueue(e);return{size:t.currentSize,maxSize:t.maxSize,status:t.status,type:t.type,items:t.getAll().map(e=>({rules:e.rules,quantity:e.quantity}))}}}var _PlayerApi_gameApi,SlotType,ReplayEventType,ChatRecipientType,_ProductionApi_production=new WeakMap,PlayerApi_classPrivateFieldSet=function(e,t,i,r,s){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!s)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!s:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?s.call(e,i):s?s.value=i:t.set(e,i),i},PlayerApi_classPrivateFieldGet=function(e,t,i,r){if("a"===i&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?r:"a"===i?r.call(e):r?r.value:t.get(e)};class PlayerApi{constructor(e,t,i,r){this.name=e,this.actions=i,this.production=r,_PlayerApi_gameApi.set(this,void 0),PlayerApi_classPrivateFieldSet(this,_PlayerApi_gameApi,t,"f")}getPlayerData(){return PlayerApi_classPrivateFieldGet(this,_PlayerApi_gameApi,"f").getPlayerData(this.name)}isDefeated(){return PlayerApi_classPrivateFieldGet(this,_PlayerApi_gameApi,"f").isPlayerDefeated(this.name)}isAlliedWith(e){return PlayerApi_classPrivateFieldGet(this,_PlayerApi_gameApi,"f").areAlliedPlayers(this.name,e)}canPlaceBuilding(e,t){return PlayerApi_classPrivateFieldGet(this,_PlayerApi_gameApi,"f").canPlaceBuilding(this.name,e,t)}getVisibleUnits(e,t=()=>!0){return PlayerApi_classPrivateFieldGet(this,_PlayerApi_gameApi,"f").getVisibleUnits(this.name,e,t)}}_PlayerApi_gameApi=new WeakMap;class BotContext{constructor(e,t,i){this.game=e,this.player=t,this.logger=i}}class BotManager{static factory(e,t,i,r){return new this(e,new ActionQueue,t,i,r)}constructor(e,t,i,r,s){this.actionFactory=e,this.actionQueue=t,this.botFactory=i,this.botDebugIndex=r,this.actionLogger=s,this.bots=new Map,this.disposables=new CompositeDisposable}init(t){this.gameApi=new GameApi(t,!0);let e=new EventsApi(t.events);var i,r;for(i of t.getCombatants().filter(e=>e.isAi))this.bots.set(i,this.botFactory.create(i));this.updateDebugBotIndex(this.botDebugIndex.value,t);let s=e=>this.updateDebugBotIndex(e,t);this.botDebugIndex.onChange.subscribe(s),this.disposables.add(()=>this.botDebugIndex.onChange.unsubscribe(s)),e.subscribe(t=>this.bots.forEach(e=>e.onGameEvent(t,this.gameApi))),this.disposables.add(e);for(r of this.bots.values()){var a=new PlayerApi(r.name,this.gameApi,new ActionsApi(t,this.actionFactory,this.actionQueue,r),new ProductionApi(t.getPlayerByName(r.name).production)),n=new LoggerApi(AppLogger.get(r.name),this.gameApi);r.setGameApi(this.gameApi),r.setActionsApi(a.actions),r.setProductionApi(a.production),r.setLogger(n),r.setContext?.(new BotContext(this.gameApi,a,n)),r.onGameInit?.(this.gameApi)}}onGameStart(){if(!this.gameApi)throw new Error("Bot manager is not initialized");for(var e of this.bots.values())e.onGameStart(this.gameApi)}update(e){var t,i;for(t of this.actionQueue.dequeueAll()){t.process();var r=t.print();r&&this.actionLogger.debug(`(${t.player.name})@${e.currentTick}: `+r)}for(i of e.getCombatants().filter(e=>e.isAi))this.bots.get(i).onGameTick(this.gameApi)}updateDebugBotIndex(e,t){var i,r=0<e?t.getAiPlayerName(e):void 0;for(i of this.bots.values())i.setDebugMode(i.name===r)}dispose(){this.gameApi=void 0,this.bots.clear(),this.disposables.dispose()}}class GameFactory{static create(e,t,i,r,s,a,n,o,l,h,c,u,d,p,g,m,y){let T=i.clone().mergeWith(a);for(var f of n)T.mergeWith(f);T.mergeWith(e);var v=r.clone().mergeWith(e.artOverrides??new IniFile);let b=new Rules(T,p);a=new Art(b,v,e,p),n=new Ai(s);b.applySpecialFlags(e.specialFlags),GameOptSanitizer.sanitize(h,b);let w=new Rules(i),S=w.getMultiplayerCountries(),A=[...w.getMultiplayerColors().values()],_=Prng.factory(o,l),O=new GameMap(e,t,b,_.generateRandomInt.bind(_));r=new World,v=c.getById(h.gameMode).type,p=new PlayerList,s=new Alliances(p),i=new UnitSelection,e=new BoxedVar(1),t=new ObjectFactory(O.tiles,O.tileOccupation,O.bridges,e),c=new ActionFactory,d=new BotFactory(d),y=BotManager.factory(c,d,m,y);let E=new Game(r,O,b,a,n,o,l,h,v,p,i,s,e,t,y);(new ActionFactoryReg).register(c,E,void 0),E.traits.add(new PowerTrait_PowerTrait),E.sellTrait=new SellTrait(E,b.general),E.traits.add(E.sellTrait),E.traits.add(new RadarTrait_RadarTrait);let C=new ProductionTrait(b,g);E.traits.add(C),E.mapShroudTrait=new MapShroudTrait(O,s),E.traits.add(E.mapShroudTrait),E.mapRadiationTrait=new MapRadiationTrait(O),E.traits.add(E.mapRadiationTrait),E.mapLightingTrait=new MapLightingTrait(b.audioVisual,O.getLighting()),E.traits.add(E.mapLightingTrait),E.traits.add(new SuperWeaponsTrait),E.traits.add(new SharedDetectDisguiseTrait_SharedDetectDisguiseTrait),E.traits.add(new SharedDetectCloakTrait),E.crateGeneratorTrait=new CrateGeneratorTrait(h.cratesAppear),E.traits.add(E.crateGeneratorTrait),u||(E.stalemateDetectTrait=new StalemateDetectTrait,E.traits.add(E.stalemateDetectTrait));let k=new PlayerFactory(b,h,C.getAvailableObjects()),P=GameOptRandomGen.factory(o,l),I=P.generateColors(h),B=P.generateCountries(h,w),N=P.generateStartLocations(h,O.startingLocations),R=[...h.humanPlayers,...h.aiPlayers].filter(isNotNullOrUndefined);return R.forEach(e=>{let t,i,r;if(isHumanPlayerInfo(e)?(t=e.name,i=!1):(t=E.getAiPlayerName(e),i=!0,r=e.difficulty),e.countryId!==OBS_COUNTRY_ID){var s=B.get(e)??e.countryId,a=I.get(e)??e.colorId,e=N.get(e)??e.startPos;if(s===RANDOM_COUNTRY_ID)throw new Error("Random country should have been resolved by now");if(a===RANDOM_COLOR_ID)throw new Error("Random color should have been resolved by now");if(e===RANDOM_START_POS)throw new Error("Random start location should have been resolved by now");s=S[s].name,s=Country.factory(s,b),a=A[a];E.addPlayer(k.createCombatant(t,s,e,a,i,r))}else E.addPlayer(k.createObserver(t,b))}),E.addPlayer(k.createNeutral(b,"@@NEUTRAL@@")),E}}class AiPlayTurnManager{constructor(e,t,i,r,s,a){this.game=e,this.inputActions=t,this.replayRecorder=i,this.actionSerializer=r,this.actionFactory=s,this.actionLogger=a,this.errorState=!1}init(){this.gameTurnMillis=1e3/(this.game.speed.value*GameSpeed.BASE_TICKS_PER_SECOND)}setErrorState(){this.errorState=!0}getErrorState(){return this.errorState}getTurnMillis(){return this.gameTurnMillis}doGameTurn(){if(!this.errorState){if(this.game.status!==GameStatus.Ended){var t,e=this.inputActions.dequeueAll();const r=new Map;for(t of e){var i=this.actionSerializer.getActionPayload(t);let e=r.get(t.player);e||(e=[],r.set(t.player,e)),e.push(i)}this.replayRecorder.recordActions(this.game.currentTick,new Map([...r].map(([e,t])=>[this.game.getPlayerNumber(e),t]))),r.forEach((t,i)=>{if(!t.length){let e=new NoAction;e.player=i,t.push(this.actionSerializer.getActionPayload(e))}}),this.processActions(r)}this.game.update()}}processActions(e){[...e].forEach(([i,e])=>e.forEach(e=>{let t=this.actionFactory.create(e.id);t.player=i,t.unserialize(e.params),t.process();e=t.print();e&&this.actionLogger?.debug(`(${i.name})@${this.game.currentTick}: `+e)}))}dispose(){}}!function(e){e[e.Closed=0]="Closed",e[e.Open=1]="Open",e[e.OpenObserver=2]="OpenObserver",e[e.Player=3]="Player",e[e.Ai=4]="Ai"}(SlotType=SlotType||{});class MapNameLegacyEncoder{encode(e){let r=[],s=0;return e.split("").forEach((e,t)=>{var i=e.charCodeAt(0)<<2*t-7*s,e=127&i,t=i>>7&127,i=i>>14&127;i&&s++,r.push(e,t),i&&r.push(i)}),r.push(0,0),2<=e.length&&r.push(0),r=r.map(e=>128^e),r.map(e=>String.fromCharCode(e)).join("")}decode(e){let i=e.split("").map(e=>e.charCodeAt(0));for(i=i.map(e=>128^e);0===i[i.length-1];)i.pop();let r=[],s=0,a=0;for(;i.length;){var n=r.length,o=i.shift(),l=i.shift();let e=0,t=!1;(-1!==[1,2,3].indexOf(i[0])||n>s+3)&&(e=i.shift(),s=n,t=!0);n=(e<<14|l<<7|o)>>2*n-7*a;r.push(127&n),t&&a++}return r.map(e=>String.fromCharCode(e)).join("")}}class FileNameEncoder{encode(e){return e.match(/^[a-z0-9-_]+\.[a-z]{3}$/i)?e:Base64.encode(utf16ToBinaryString(e))}decode(e){return e.match(/\.[a-z]{3}$/i)?e:binaryStringToUtf16(Base64.decode(e))}}class Serializer{serializeOptions(e,t=!1){let i=e.gameMode,r=t?(new MapNameLegacyEncoder).encode(e.mapTitle):Base64.encode(utf16ToBinaryString(e.mapTitle)),s=(new FileNameEncoder).encode(e.mapName);t=["0","0",6-e.gameSpeed,e.credits,e.unitCount,Number(e.shortGame),Number(e.superWeapons),Number(e.buildOffAlly),Number(e.mcvRepacks),Number(e.cratesAppear),i,Number(e.hostTeams??!1),r,e.maxSlots,Number(e.mapOfficial),e.mapSizeBytes,s,e.mapDigest,Number(e.destroyableBridges),Number(e.multiEngineer),Number(e.noDogEngiKills),...e.unknown?[e.unknown]:[]].join(",");return t+`:${e.humanPlayers.map(e=>""+e.name+`,${e.countryId},${e.colorId},${e.startPos},${e.teamId},0,0,0`).join(",")}:@:${this.serializeAiOpts(e.aiPlayers)},`}serializeAiOpts(e){return e.map(e=>e?`${e.difficulty},${e.countryId},${e.colorId},${e.startPos},`+e.teamId:"0,-1,-1,-1,-1").join(",")}serializePingData(e){return e.length+","+e.map(e=>e.playerName+","+e.ping).join(",")}serializeSlotData(e){return e.map(e=>{if(e.type===SlotType.Closed)return"@Closed@";if(e.type===SlotType.Open)return"@Open@";if(e.type===SlotType.OpenObserver)return"@OpenObserver@";if(e.type===SlotType.Ai){if(e.difficulty===AiDifficulty.Easy)return"@EasyAI@";if(e.difficulty===AiDifficulty.Medium)return"@MediumAI@";if(e.difficulty===AiDifficulty.Brutal)return"@HardAI@"}else if(e.type===SlotType.Player)return e.name;throw new Error("Unexpected slot info with type "+SlotType[e.type])}).join(",")+","}serializeLoadInfo(e){return e.map(e=>[e.name,e.status,e.loadPercent,e.ping,e.lagAllowanceMillis].join(",")).join(",")}serializePlayerActions(e){let t=new DataStream;t.writeUint8(e.length);for(var{id:i,params:r}of e)if(t.writeUint8(i),t.writeUint16(r.byteLength),0<r.byteLength){if(r.byteLength>Serializer.MAX_ACTION_PAYLOAD_SIZE-t.position)throw console.error(`Action #${i} payload exceeds max data size`,r),new RangeError("Maximum payload data size exceeded");t.writeUint8Array(r)}return t.toUint8Array()}serializeAllPlayerActions(e,t){e.writeUint8(t.size);for(var[i,r]of t){e.writeUint8(i);var s=this.serializePlayerActions(r);if(e.writeUint16(s.byteLength),0<s.byteLength){if(s.byteLength>Serializer.MAX_ACTION_PAYLOAD_SIZE)throw console.error(`Player #${i} actions payload exceeds max data size`,r),new RangeError("Maximum payload data size exceeded");e.writeUint8Array(s)}}}serializeMapData(e){return binaryStringToUint8Array(e)}}Serializer.MAX_ACTION_PAYLOAD_SIZE=65536;class Parser{parseOptions(e){let t={},[i,r,,s]=e.split(":"),a=i.split(",");a.shift(),a.shift(),t.gameSpeed=6-Number(a.shift()),t.credits=Number(a.shift()),t.unitCount=Number(a.shift()),t.shortGame=Boolean(Number(a.shift())),t.superWeapons=Boolean(Number(a.shift())),t.buildOffAlly=Boolean(Number(a.shift())),t.mcvRepacks=Boolean(Number(a.shift())),t.cratesAppear=Boolean(Number(a.shift())),t.gameMode=Number(a.shift()),t.hostTeams=Boolean(Number(a.shift()));e=a.shift();return t.mapTitle=Base64.isBase64(e)?binaryStringToUtf16(Base64.decode(e)):(new MapNameLegacyEncoder).decode(e),t.maxSlots=Number(a.shift()),t.mapOfficial=Boolean(Number(a.shift())),t.mapSizeBytes=Number(a.shift()),t.mapName=(new FileNameEncoder).decode(a.shift()),t.mapDigest=a.shift(),t.destroyableBridges=Boolean(Number(a.shift()??"1")),t.multiEngineer=Boolean(Number(a.shift()??"0")),t.noDogEngiKills=Boolean(Number(a.shift()??"0")),t.unknown=a.length?a.join(","):void 0,t.humanPlayers=this.parsePlayerOpts(r),t.aiPlayers=this.parseAiOpts(s?.slice(0,-1)),t}parsePlayerOpts(e){var i=e.split(",");if(i.length%8!=0)throw new Error("Couldn't parse gameopt: unexpected players data length "+i.length);let r=[];for(let e=0,t=Math.floor(i.length/8);e<t;++e){var s={name:i[8*e],countryId:Number(i[8*e+1]),colorId:Number(i[8*e+2]),startPos:Number(i[8*e+3]),teamId:Number(i[8*e+4])};r.push(s)}return r}parseAiOpts(e){let i=[];if(e){var r=e.split(",");if(r.length%5!=0)throw new Error("Couldn't parse gameopt: unexpected ai data length "+r.length);for(let e=0,t=Math.floor(r.length/5);e<t;++e){var s={difficulty:Number(r[5*e]),countryId:Number(r[5*e+1]),colorId:Number(r[5*e+2]),startPos:Number(r[5*e+3]),teamId:Number(r[5*e+4])};i.push(-1!==s.countryId?s:void 0)}}return i}parseTopic(e){var t=e.split(",");if(!(t.length<6)){var i=t[0],r=Number(t[1]),s=i[2],a=t[2],n=t[3],e=t[4],i=(new FileNameEncoder).decode(t[5]);return{description:t[6]?binaryStringToUtf16(Base64.decode(t[6])):"",modHash:r,modName:t[7]?binaryStringToUtf16(Base64.decode(t[7])):void 0,aiPlayers:Number(a),maxPlayers:Number(s),observers:Number(n),observable:Boolean(Number(e)),mapName:i}}}parsePingData(e){var i=e.split(",").slice(1);if(i.length%2)throw new Error("Couldn't parse gameopt: unexpected ping data length "+i.length);let r=[];for(let e=0,t=Math.floor(i.length/2);e<t;++e)r.push({playerName:i[2*e],ping:Number(i[2*e+1])});return r}parseSlotData(e){var i;let r=[];for(i of e.slice(1,-1).split(",")){let t={};if("@Closed@"===i)t.type=SlotType.Closed;else if("@Open@"===i)t.type=SlotType.Open;else if("@OpenObserver@"===i)t.type=SlotType.OpenObserver;else if(-1!==["@EasyAI@","@MediumAI@","@HardAI@"].indexOf(i)){t.type=SlotType.Ai;let e;if("@EasyAI@"===i)e=AiDifficulty.Easy;else if("@MediumAI@"===i)e=AiDifficulty.Medium;else{if("@HardAI@"!==i)throw new Error("Couldn't parse gameopt: unknown slot type "+i);e=AiDifficulty.Brutal}t.difficulty=e}else t.type=SlotType.Player,t.name=i;r.push(t)}return r}parsePlayerActions(e){let t=new DataStream(e);var i=t.readUint8();let r=[];for(let e=0;e<i;++e){var s=t.readUint8(),a=t.readUint16(),a=0<a?t.readUint8Array(a):new Uint8Array;r.push({id:s,params:a})}return r}parseAllPlayerActions(t){var i=t.readUint8();let r=new Map;for(let e=0;e<i;++e){var s=t.readUint8(),a=t.readUint16(),a=0<a?t.readUint8Array(a):new Uint8Array,a=this.parsePlayerActions(a);r.set(s,a)}return r}parseMapData(e){return uint8ArrayToBinaryString(e)}}class ReplayEvent{constructor(e,t){this.type=e,this.tickNo=t}}!function(e){e[e.TurnActions=0]="TurnActions",e[e.ChatMessage=1]="ChatMessage",e[e.Taunt=2]="Taunt"}(ReplayEventType=ReplayEventType||{});class ChatMessageReplayEvent extends ReplayEvent{constructor(e){super(ReplayEventType.ChatMessage,e)}serialize(){return this.payload.playerId+":"+Base64.encode(utf16ToBinaryString(this.payload.message))}unserialize(e){var[t,e]=e.split(":"),t=Number(t),e=binaryStringToUtf16(Base64.decode(e));this.payload={playerId:t,message:e}}}class TauntReplayEvent extends ReplayEvent{constructor(e){super(ReplayEventType.Taunt,e)}serialize(){return this.payload.playerId+":"+this.payload.tauntNo}unserialize(e){var[t,e]=e.split(":"),t=Number(t),e=Number(e);this.payload={playerId:t,tauntNo:e}}}class TurnActionsReplayEvent extends ReplayEvent{constructor(e,t,i){super(ReplayEventType.TurnActions,i),this.gameOptsParser=e,this.gameOptsSerializer=t}serialize(){let e=new DataStream;return this.gameOptsSerializer.serializeAllPlayerActions(e,new Map(this.payload)),uint8ArrayToBase64String(e.toUint8Array())}unserialize(e){e=new DataStream(base64StringToUint8Array(e)),e=this.gameOptsParser.parseAllPlayerActions(e);this.payload=[...e]}}class ReplayEventFactory{constructor(e,t){this.gameOptsParser=e,this.gameOptsSerializer=t}create(e,t){switch(e){case ReplayEventType.TurnActions:return new TurnActionsReplayEvent(this.gameOptsParser,this.gameOptsSerializer,t);case ReplayEventType.ChatMessage:return new ChatMessageReplayEvent(t);case ReplayEventType.Taunt:return new TauntReplayEvent(t);default:throw new Error(`Unsupported replay event type "${e}" at game tick "${t}"`)}}}async function*makeTextFileLineIterator(e){const t=new TextDecoder("utf-8");let i=e.stream().getReader(),{value:r,done:s}=await i.read();r=r?t.decode(r,{stream:!0}):"";let a=/\r\n|\n|\r/gm,n=0;for(;;){var o=a.exec(r);if(o)yield r.substring(n,o.index),n=a.lastIndex;else{if(s)break;o=r.substr(n);({value:r,done:s}=await i.read()),r=o+(r?t.decode(r,{stream:!0}):""),n=a.lastIndex=0}}n<r.length&&(yield r.substr(n))}const REPLAY_VERSION=6,supportedReplayVersions=[5,6];class Replay{constructor(){this.name="",this.events=[]}static sanitizeFileName(e,t="_"){return e.replace(/[/?<>\\:*|"]/g,t).replace(/[\x00-\x1f\x7f\x80-\x9f]/g,t).slice(0,this.maxNameLength)}init(e,t,i,r,s){this.gameId=e,this.gameTimestamp=t,this.gameOpts=i,this.engineVersion=r,this.modHash=s,this.name=Replay.sanitizeFileName(this.gameOpts.mapTitle+" "+(new Date).toISOString().replace(/(\.|,)\d+Z$/,"Z")),this.timestamp=Date.now()}writeEvent(...e){this.events.push(...e)}finish(e){this.endTick=e}getEvents(){return this.events}*flush(){if(!this.gameOpts)throw new Error("Game options must be set first");if(!this.engineVersion)throw new Error("Engine version is not set");if(void 0===this.modHash)throw new Error("Mod hash is not set");let e=new Serializer,t=this.getHeaderTag()+"\n";for(t+=`ENGINE ${this.engineVersion} ${this.modHash}
2
- `,t+=[this.gameId,this.gameTimestamp,e.serializeOptions(this.gameOpts)].join(" ")+"\n",yield t,t="";void 0===this.endTick||this.events.length;){for(var i of this.events)t+=i.tickNo+"="+i.type+"|"+i.serialize()+"\n";this.events.length=0,yield t,t=""}t+=this.getEndTag()+" "+this.endTick+"\n",this.debugInfo&&(t+=Base64.encode(utf16ToBinaryString(this.debugInfo))+"\n"),yield t}serialize(){if(void 0===this.endTick)throw new Error("Replay is not finished");let e="";var t,i=this.events.slice();for(t of this.flush())e+=t;return this.events=i,e}async parseHeader(e){let t=0,i,r,s,a,n,o;var l;for await(l of"string"==typeof e?e.split("\n"):makeTextFileLineIterator(e)){if(0===t)i=this.readReplayVersion(l);else if(1===t){if(!l.match(Replay.engineLineRegex))throw new Error("Missing or invalid game engine version line");var h=l.split(" ");r=h[1],s=Number(i<4?"0":h[2])}else{if(2!==t)break;if(!l.match(/^([a-zA-Z0-9-]+) \d+ .*$/))throw new Error("Missing or invalid game id/time/opts line");var[c,u,h]=l.split(" ");a=c,n=Number(u),o=i<6?Base64.decode(h):h}t++}if(t<3)throw new Error("Bad replay header");return{replayVersion:i,engineVersion:r,modHash:s,gameId:a,gameTimestamp:n,gameOptsSerialized:o}}unserialize(e,t){let i=e.split("\n");var r=this.readReplayVersion(i.shift()||"");if(!supportedReplayVersions.includes(r))throw new Error("Unsupported replay version "+r);let s=new Parser,a=i.shift();if(!a||!a.match(Replay.engineLineRegex))throw new Error("Missing or invalid game engine version line");var[,n,o]=a.split(" ");let l=i.shift();if(!l)throw new Error("Missing game id/time/opts line");e=l.match(/^([a-zA-Z0-9-]+) (\d+) (.*)$/);if(!e)throw new Error("Invalid game id/time/opts line");let[,h,c,u]=e;r<6&&(u=Base64.decode(u));r=s.parseOptions(u);this.init(h,Number(c),r,n,Number(o)),this.name=t.name,this.timestamp=t.timestamp;let d,p=!1;for(;d=i.shift();){if(d.startsWith(this.getEndTag())){p=!0;break}var g=d.match(/^(\d+)=(\d+)\|(.+)$/);if(!g)throw new Error(`Invalid event line "${d}"`);var[,m,y,g]=g,m=Number(m),y=Number(y);let e=new ReplayEventFactory(s,new Serializer).create(y,m);e.unserialize(g),this.writeEvent(e)}if(!p)throw new Error("Incomplete replay data");t=d.match(new RegExp(`^${this.getEndTag()} (\\d+)$`));if(!t)throw new Error("Invalid end tag");this.endTick=Number(t[1]),1<=i.length&&(this.debugInfo=binaryStringToUtf16(Base64.decode(i[0])))}getHeaderTag(){return"RA2TSREPL_v"+REPLAY_VERSION}readReplayVersion(e){e=e.match(/^RA2TSREPL_v(\d+)$/);if(!e||e.length<2)throw new Error("Unknown replay format");return Number(e[1])}getEndTag(){return"END"}}Replay.extension=".rpl",Replay.maxNameLength=128,Replay.engineLineRegex=/^ENGINE \d+\.\d+( \d+)?$/;class ReplayRecorder{constructor(e,t,i,r){this.replay=e,this.playerId=t,this.humanPlayers=i,this.actionSerializer=r}recordActions(t,i){if(Array.isArray(i)){let e=new TurnActionsReplayEvent(new Parser,new Serializer,t);e.payload=[[this.playerId,i.map(e=>this.actionSerializer.getActionPayload(e))]],this.replay.writeEvent(e)}else if(this.hasActualActions(i)){let e=new TurnActionsReplayEvent(new Parser,new Serializer,t);e.payload=[...i].map(([e,t])=>[e,t]),this.replay.writeEvent(e)}}recordChatMessage(e,t,i){let r=new ChatMessageReplayEvent(e);r.payload={playerId:this.humanPlayers.findIndex(e=>e.name===t),message:i},this.replay.writeEvent(r)}recordTaunt(e,t,i){let r=new TauntReplayEvent(e);r.payload={playerId:this.humanPlayers.findIndex(e=>e.name===t),tauntNo:i},this.replay.writeEvent(r)}hasActualActions(e){return!![...e.values()].find(e=>e.find(e=>e.id!==ActionType.NoAction))}}class ActionSerializer{getActionPayload(e){return{id:e.actionType,params:e.serialize()}}}class OperationCanceledError extends Error{constructor(e){super(),this.cancellationToken=e}}const CANCEL=Symbol(),REGISTER=Symbol();class CancellationToken{constructor(e){this.source=e,this.cancelled=!1}throwIfCancelled(){if(this.isCancelled())throw new OperationCanceledError(this)}isCancelled(){return!0===this.cancelled}[CANCEL](){this.cancelled=!0}register(e){this.source[REGISTER](e)}}class EventDispatcher_EventDispatcher{constructor(){this.listeners=new Set}subscribe(e){this.listeners.add(e)}unsubscribe(e){this.listeners.delete(e)}subscribeOnce(i){let r=(e,t)=>{i(e,t),this.unsubscribe(r),r=void 0};this.subscribe(r)}dispatch(t,i){this.listeners.forEach(e=>e(i,t))}asEvent(){return this}}class CancellationTokenSource{constructor(){this.onCancel=new EventDispatcher_EventDispatcher,this.token=new CancellationToken(this)}cancel(){this.token[CANCEL](),this.onCancel.dispatch(this,void 0)}[REGISTER](e){this.onCancel.subscribe(()=>e()),this.token.isCancelled()&&e()}}async function sleep(t){return new Promise(e=>{setTimeout(()=>e(),t)})}function throttle(r,s){let a=!1,n=Number.NEGATIVE_INFINITY;return async function(...e){var t,i;a||(i=(t=Date.now())-n,n=s<=i?t:(a=!0,await sleep(s-i),a=!1,Date.now()),await r.apply(this,e))}}function Throttle(s){return(e,t,i)=>{var r=i.value;i.value=throttle(r,s)}}class IrcConnection{constructor(e,t){this.options=e,this.logger=t,this.timeout=5,this._onMessage=new EventDispatcher,this._onError=new EventDispatcher,this._onClose=new EventDispatcher,this.messageBuffer=""}get onMessage(){return this._onMessage.asEvent()}get onError(){return this._onError.asEvent()}get onClose(){return this._onClose.asEvent()}async connect(r,s){let e=s?.timeoutSeconds?setTimeout(()=>this.close(),1e3*s.timeoutSeconds):void 0;return s?.cancelToken?.register(()=>{e&&(clearTimeout(e),this.close())}),new Promise((e,t)=>{this.socket=new WebSocket(r),"arraybuffer"!==this.socket.binaryType&&(this.socket.binaryType="arraybuffer");let i=e=>{this.socket.removeEventListener("error",i),s?.cancelToken?.isCancelled()?t(new OperationCanceledError(s.cancelToken)):t(new IrcConnection.ConnectError(`Connection to "${r}" failed`))};this.socket.addEventListener("open",()=>{this.socket.removeEventListener("error",i),this.socket.addEventListener("error",e=>this.handleError(e)),this.handleOpen(),e()}),this.socket.addEventListener("error",i),this.socket.addEventListener("close",e=>this.handleClose(e)),this.socket.addEventListener("message",e=>{e.data instanceof ArrayBuffer?this.handleMessage(new Uint8Array(e.data)):this.handleMessage(e.data)})}).finally(()=>{e&&clearTimeout(e)})}handleOpen(){this.logger.info("Connection open to "+this.socket.url)}handleError(e){this.logger.error("Connection error",e),this._onError.dispatch(this,e)}handleClose(e){this.logger.info(`Connection closed (${this.socket.url})`,e),this._onClose.dispatch(this,e)}handleMessage(e){if("string"!=typeof e){if(e[0]===this.options.binaryRplPrefix)return void this._onMessage.dispatch(this,e.slice(1));e=uint8ArrayToBinaryString(e)}this.logger.enabledFor(AppLogger.DEBUG)&&this.logger.debug("Got message:","string"==typeof e?this.options.logFilter?.(e)??e:e),e=this.messageBuffer+e,this.messageBuffer="";let t=e.split(/\r?\n/);e=t.pop();e.length&&(this.messageBuffer=e),t.filter(e=>!!e).forEach(e=>this._onMessage.dispatch(this,e))}async sendCommand(e,l){if(l.replyStartCode&&!l.replyEndCode)throw new Error("Invalid argument. Expected a reply end code, but got only a start code.");let h=[];return await this.sendRawCommand(e,(e,s,a,n)=>{let o=(e,t)=>{if("number"==typeof e)return t.code===e;let[i,r]=e;return t.code===i&&r(t)};if("string"!=typeof e){if(e[0]===this.options.binaryRplPrefix)return!1;e=uint8ArrayToBinaryString(e)}return l.replyRawText?(a(e.split(/\r?\n/).map(e=>({raw:e,time:s}))),!0):e.split(/\r?\n/).filter(e=>!!e).some(e=>(e=>{if(l.replyMatch){if(l.replyMatch.exec(e))return a([{raw:e,time:s}]),!0;if(!l.replyCodes)return!1}if(!l.replyEndCode&&!l.replyCodes)return a([{raw:e,time:s}]),!0;var[,t,...i]=e.split(" "),t=parseInt(t,10);let r={raw:e,code:t,params:i,time:s};if(l.replyEndCode)return l.replyCodes&&l.replyCodes.some(e=>o(e,r))?(a([r]),!0):(l.replyHeartbeatCodes&&-1!==l.replyHeartbeatCodes.indexOf(t)&&n(l.heartbeatTimeout),(t===l.replyStartCode||l.replyBodyCodes&&-1!==l.replyBodyCodes.indexOf(t)||t===l.replyEndCode)&&h.push(r),t===l.replyEndCode&&(a(h),!0));if(void 0===l.replyCodes)throw new Error("List of replyCodes must be specified when not using start/end codes");return!!l.replyCodes.some(e=>o(e,r))&&(a([r]),!0)})(e))},l.timeout)}async sendBinCommand(e,s){const a=this.options.binaryRplPrefix;if(!a)throw new Error("Must configure binary message reply prefix to send binary commands");const t=this.options.binaryReqPrefix;if(!t)throw new Error("Must configure binary message request prefix to send binary commands");if(e[0]!==t)throw new Error("Binary command must start with the magic prefix 0x"+t.toString(16));return await this.sendRawCommand(e,(e,t,i)=>{if("string"==typeof e||e[0]!==a)return!1;var r=e[1];return-1!==s.replyCodes.indexOf(r)&&(i({code:r,data:e.slice(2),time:t}),!0)},s.timeout)}sendRawCommand(u,d,p){return new Promise((t,i)=>{let e=!1,r,s=e=>{clearTimeout(r),void 0!==e&&Number.isFinite(e)&&(r=setTimeout(o,1e3*(e??p??this.timeout)))},a=e=>{clearTimeout(r),t(e)},n=e=>{this.socket.removeEventListener("message",c),this.socket.removeEventListener("close",l),clearTimeout(r),r=void 0,i(e)},o=()=>{var e="string"==typeof u?this.options.logFilter?.(u)??u:"0x"+u[1].toString(16);n(new IrcConnection.NoReplyError("Timeout reached for command "+e))},l=async()=>{for(;e;)await sleep(10);h||n(new IrcConnection.SocketError("Connection was closed prematurely"))},h=!1,c=e=>{var t;h||(t=Date.now(),e.data instanceof ArrayBuffer?h||d(new Uint8Array(e.data),t,a,s)&&(h=!0,this.socket.removeEventListener("message",c),this.socket.removeEventListener("close",l)):d(e.data,t,a,s)&&(h=!0,this.socket.removeEventListener("message",c),this.socket.removeEventListener("close",l)))};if(this.socket&&this.socket.readyState===WebSocket.OPEN){r=setTimeout(o,1e3*(p??this.timeout)),this.socket.addEventListener("message",c),this.socket.addEventListener("close",l);try{this.sendMessage(u)}catch(e){n(e)}}else n(new IrcConnection.SocketError("Send command failed. Socket is not open."+(this.socket?` (readyState = ${this.socket.readyState})`:"")))})}sendMessage(e){if(!this.socket||this.socket.readyState!==WebSocket.OPEN)throw new IrcConnection.SocketError("Socket is not open"+(this.socket?` (readyState = ${this.socket.readyState})`:""));this.logger.enabledFor(AppLogger.DEBUG)&&this.logger.debug("Sent message:","string"==typeof e?this.options.logFilter?.(e)??e:e),"string"==typeof e&&(e+="\r\n");let t;t="binary"===this.options.mode&&"string"==typeof e?binaryStringToUint8Array(e):e,this.socket.send(t)}async ping(e){var t=Date.now();return(await this.sendCommand("ping :"+t,{replyMatch:new RegExp("^:[^ ]+ PONG [^ :]+ :"+t,"i"),timeout:e}))[0].time-t}close(){this.socket&&this.socket.close()}isOpen(){return this.socket&&this.socket.readyState===WebSocket.OPEN}}!function(e){class t extends Error{constructor(e){super(e)}}e.NoReplyError=t;class i extends Error{constructor(e){super(e)}}e.SocketError=i;class r extends Error{constructor(e){super(e)}}e.ConnectError=r}(IrcConnection=IrcConnection||{});const RPL_CVERS_OK=10,RPL_CVERS_OUTDATED=11,RPL_CVERS_MISSING=12,RPL_LOGGED_IN=100,RPL_ALREADY_LOGGED_IN=101,RPL_NOT_LOGGED_IN=102,RPL_BAD_LOGIN=103,RPL_TOO_MANY_LOGIN_ATTEMPTS=104,RPL_INSTANCE_CREATED=200,RPL_INSTANCE_EXISTS=201,RPL_INSTANCE_TOO_MANY=202,RPL_NOT_ENOUGH_PARAMS=300,RPL_INVALID_PARAMS=301,RPL_RATE_LIMIT_EXCEEDED=302,RPL_INSTANCE_CONNECTED=400,RPL_INSTANCE_NONEXISTENT=401,RPL_INSTANCE_NOT_ALLOWED=402,RPL_INSTANCE_ALREADY_STARTED=403,RPL_NO_INSTANCE=404,RPL_INSTANCE_NOT_RUNNING=405,RPL_INSTANCE_VERS_MISMATCH=406,RPL_GAME_OPTS=500,RPL_LOAD_INFO=600,RPL_MAP_TOO_BIG=602,RPL_MAP_ALREADY_SENT=603,RPL_GAME_START=700,RPL_GAME_DESYNC=801,RPL_NET_RATE=802,RPL_TAUNT=803,RPL_PLAYER_DISCONNECT=804,RPL_PRIVMSG_NOT_ALLOWED=805,RPL_BIN_PREFIX=2,RPL_BIN_GAME_ACTIONS=1,RPL_BIN_MAP_DATA=2,REQ_BIN_PREFIX=2,REQ_BIN_GAME_ACTIONS=1,REQ_BIN_GAME_STATE_HASH=2,REQ_BIN_PUT_MAP=3,REQ_BIN_GET_MAP=4;class GservError extends Error{constructor(e,t){super(e),this.code=t}}!function(e){(e=e.Code||(e.Code={}))[e.Unknown=0]="Unknown",e[e.OutdatedClient=1]="OutdatedClient",e[e.BadLogin=2]="BadLogin",e[e.TooManyLoginAttempts=3]="TooManyLoginAttempts",e[e.AlreadyLoggedIn=4]="AlreadyLoggedIn",e[e.InstanceNonExistent=5]="InstanceNonExistent",e[e.InstanceAlreadyExists=6]="InstanceAlreadyExists",e[e.InstanceNotAllowed=7]="InstanceNotAllowed",e[e.InstanceAlreadyStarted=8]="InstanceAlreadyStarted",e[e.InstanceVersMismatch=9]="InstanceVersMismatch",e[e.CreatedTooManyInstances=10]="CreatedTooManyInstances"}(GservError=GservError||{});const API_VERSION=2,RECIPIENT_ALL="#all",RECIPIENT_TEAM="#team",TURN_TIMEOUT_MILLIS=3e4,LAG_STATE_THRESH_MILLIS=1e3,CON_INFO_THRESH_MILLIS=2e3,LAG_CHECK_INTERVAL_MILLIS=1e3,MAX_MAP_TRANSFER_BYTES=2097152;!function(e){e[e.Channel=0]="Channel",e[e.Page=1]="Page",e[e.Whisper=2]="Whisper"}(ChatRecipientType=ChatRecipientType||{});const gservErrorCodeMap=new Map([[RPL_BAD_LOGIN,GservError.Code.BadLogin],[RPL_TOO_MANY_LOGIN_ATTEMPTS,GservError.Code.TooManyLoginAttempts],[RPL_ALREADY_LOGGED_IN,GservError.Code.AlreadyLoggedIn],[RPL_INSTANCE_EXISTS,GservError.Code.InstanceAlreadyExists],[RPL_INSTANCE_TOO_MANY,GservError.Code.CreatedTooManyInstances],[RPL_INSTANCE_NONEXISTENT,GservError.Code.InstanceNonExistent],[RPL_INSTANCE_NOT_ALLOWED,GservError.Code.InstanceNotAllowed],[RPL_INSTANCE_ALREADY_STARTED,GservError.Code.InstanceAlreadyStarted],[RPL_INSTANCE_VERS_MISMATCH,GservError.Code.InstanceVersMismatch]]);class GservConnection{get onError(){return this.con.onError}get onClose(){return this.con.onClose}get onLoadInfo(){return this._onLoadInfo.asEvent()}get onGameStart(){return this._onGameStart.asEvent()}get onGameActions(){return this._onGameActions.asEvent()}get onGameDesync(){return this._onGameDesync.asEvent()}get onRateChange(){return this._onRateChange.asEvent()}get onChatMessage(){return this._onChatMessage.asEvent()}get onTaunt(){return this._onTaunt.asEvent()}get onPlayerDisconnect(){return this._onPlayerDisconnect.asEvent()}get onPrivMsgNotAllowed(){return this._onPrivMsgNotAllowed.asEvent()}static factory(e){return new this(new IrcConnection({mode:"text",binaryRplPrefix:RPL_BIN_PREFIX,binaryReqPrefix:REQ_BIN_PREFIX,logFilter:e=>e.replace(/^(user [^ ]+) ([^ ]+)/i,"$1 <redacted>").replace(/^((:.+!.+@.+)?privmsg ([^ ]+ )+):(.+)\r?\n?$/i,"$1:<redacted>")},e))}constructor(e){this._onLoadInfo=new EventDispatcher,this._onGameStart=new EventDispatcher,this._onGameActions=new EventDispatcher,this._onGameDesync=new EventDispatcher,this._onRateChange=new EventDispatcher,this._onChatMessage=new EventDispatcher,this._onTaunt=new EventDispatcher,this._onPlayerDisconnect=new EventDispatcher,this._onPrivMsgNotAllowed=new EventDispatcher,this.handleMessage=t=>{if("string"==typeof t){let e=t.split(" ");var i,r;"ping"===e[0]?this.isOpen()&&this.con.sendMessage("pong"+(e[1]?" "+e[1]:"")):"privmsg"===e[1].toLowerCase()?this.handlePrivMsg(t):e[1]===""+RPL_LOAD_INFO?this.handleLoadInfo(e[3]):e[1]===""+RPL_GAME_START?this.handleGameStart():e[1]===""+RPL_GAME_DESYNC?this._onGameDesync.dispatch(this):e[1]===""+RPL_NET_RATE?([i,r]=e[3].slice(1).split(","),this._onRateChange.dispatch(this,{rate:Number(i),turnNo:Number(r)})):e[1]===""+RPL_TAUNT?this._onTaunt.dispatch(this,{from:e[0].replace(/^:/,""),tauntNo:Number(e[3].replace(/^:/,""))}):e[1]===""+RPL_PLAYER_DISCONNECT?this._onPlayerDisconnect.dispatch(this,e[3].replace(/^:/,"")):e[1]===""+RPL_PRIVMSG_NOT_ALLOWED&&this._onPrivMsgNotAllowed.dispatch(this)}else t[0]===RPL_BIN_GAME_ACTIONS&&this.handlePlayerActions(t.slice(1))},this.con=e}getCurrentUser(){return this.currentUser}getServerName(){return this.serverName}async connect(e,t){return this.con.onMessage.subscribe(this.handleMessage),await this.con.connect(e,t)}close(){this.con.onMessage.unsubscribe(this.handleMessage),this.con.close(),this.currentUser=void 0}isOpen(){return this.con.isOpen()}async cvers(e){let t=await this.con.sendCommand(`cvers ${e} `+API_VERSION,{replyCodes:[RPL_CVERS_OK,RPL_CVERS_OUTDATED]});if(t[0].code===RPL_CVERS_OUTDATED){e=t[0].params?t[0].params.splice(1).join(" ").replace(/^:/,""):"unknown";throw new GservError("Cvers error: "+e,GservError.Code.OutdatedClient)}}async login(e,t){let i=await this.con.sendCommand(`user ${e} `+Base64.encode(t),{replyCodes:[RPL_LOGGED_IN,RPL_BAD_LOGIN,RPL_TOO_MANY_LOGIN_ATTEMPTS,RPL_ALREADY_LOGGED_IN],timeout:10});if(i[0].code!==RPL_LOGGED_IN){var r=gservErrorCodeMap.get(i[0].code)??GservError.Code.Unknown,t=i[0].params?i[0].params.splice(1).join(" ").replace(/^:/,""):"unknown";throw new GservError("Login error: "+t,r)}this.currentUser=e,this.serverName=i[0].raw.match(/^:([^\s]+)/)?.[1]||""}async createGame(e,t,i,r,s,a=!1){if(i.includes(" "))throw new Error("Game opts string cannot include spaces");let n=await this.con.sendCommand(`create ${e} ${t} ${i} ${r} ${s} `+Number(a),{replyCodes:[RPL_INSTANCE_CREATED,RPL_INSTANCE_EXISTS,RPL_INSTANCE_TOO_MANY,RPL_INSTANCE_NOT_ALLOWED]});if(n[0].code!==RPL_INSTANCE_CREATED){s=gservErrorCodeMap.get(n[0].code)??GservError.Code.Unknown,a=n[0].params?n[0].params.splice(1).join(" ").replace(/^:/,""):"unknown";throw new GservError("Create error: "+a,s)}}async joinGame(e,t,i){let r=await this.con.sendCommand(`join ${e} ${t} `+i,{replyCodes:[RPL_INSTANCE_CONNECTED,RPL_INSTANCE_NONEXISTENT,RPL_INSTANCE_NOT_ALLOWED,RPL_INSTANCE_ALREADY_STARTED,RPL_INSTANCE_VERS_MISMATCH]});if(r[0].code!==RPL_INSTANCE_CONNECTED){t=gservErrorCodeMap.get(r[0].code)??GservError.Code.Unknown,i=r[0].params?r[0].params.splice(1).join(" ").replace(/^:/,""):"unknown";throw new GservError("Join error: "+i,t)}}async gameOpts(){let e=await this.con.sendCommand("gameopts",{replyCodes:[RPL_GAME_OPTS]});if(!e[0].params)throw new Error("Unexpected server reply for getopts command. Missing params.");return e[0].params.splice(1).join(" ").replace(/^:/,"")}sendLoadedPercent(e){this.con.sendMessage("loaded "+e)}requestLoadInfo(){this.con.sendMessage("loadinfo")}sendGameStateHash(e,t){let i=new DataStream(10);i.dynamicSize=!1,i.writeUint8(REQ_BIN_PREFIX),i.writeUint8(REQ_BIN_GAME_STATE_HASH),i.writeUint32(e),i.writeUint32(t),this.con.sendMessage(i.toUint8Array())}sendPlayerActive(e){this.con.sendMessage("active "+(e?1:0))}sendTaunt(e){this.con.sendMessage("taunt "+e)}async ping(e){return await this.con.ping(e)}sendPlayerActions(e,t){let i=new DataStream(6);i.writeUint8(REQ_BIN_PREFIX),i.writeUint8(REQ_BIN_GAME_ACTIONS),i.writeUint32(e),i.writeUint8Array(t),this.con.sendMessage(i.toUint8Array())}sendMap(e){let t=new DataStream(2);t.writeUint8(REQ_BIN_PREFIX),t.writeUint8(REQ_BIN_PUT_MAP),t.writeUint8Array((new Serializer).serializeMapData(e)),this.con.sendMessage(t.toUint8Array())}async getMap(){let e=new DataStream(2);e.dynamicSize=!1,e.writeUint8(REQ_BIN_PREFIX),e.writeUint8(REQ_BIN_GET_MAP);var t=await this.con.sendBinCommand(e.toUint8Array(),{replyCodes:[RPL_BIN_MAP_DATA],timeout:15});return(new Parser).parseMapData(t.data)}handleLoadInfo(e){this._onLoadInfo.dispatch(this,e.replace(/^:/,""))}handleGameStart(){this._onGameStart.dispatch(this,void 0)}handlePlayerActions(e){this._onGameActions.dispatch(this,e)}sayChannel(e){this.privmsg([RECIPIENT_ALL],e)}privmsg(e,t){if(!this.currentUser)throw new Error("Must login before sending messages");t.length&&(e=e.join(","),this.con.sendMessage(`privmsg ${e} :`+t))}handlePrivMsg(e){var t=e.match(/^:([A-Za-z0-9-_]+) PRIVMSG ([A-Za-z0-9-_#']+) :(.*)/i);if(!t)throw new Error(`Unexpected PRIVMSG message format "${e}"`);var[,i,r,e]=t;let s;t=new Date;r===RECIPIENT_ALL?s={from:i,to:{type:ChatRecipientType.Channel,name:r},text:e,time:t}:r===this.currentUser&&(s={from:i,to:i===this.getServerName()?{type:ChatRecipientType.Page,name:r}:{type:ChatRecipientType.Channel,name:RECIPIENT_TEAM},text:e,time:t}),s&&this._onChatMessage.dispatch(this,s)}}const computeNetworkTurnMillis=(e,t)=>{return Math.max(1,Math.ceil(e/t))*t};class LockstepManager{get onLagStateChange(){return this._onLagStateChange.asEvent()}get onActionsSent(){return this._onActionsSent.asEvent()}get onActionsProcessed(){return this._onActionsProcessed.asEvent()}get onActionsReceived(){return this._onActionsReceived.asEvent()}constructor(e,t,i,r,s,a,n,o,l,h,c,u,d){this.game=e,this.gservCon=t,this.gameoptParser=i,this.gameoptSerializer=r,this.actionSerializer=s,this.actionFactory=a,this.inputActions=n,this.onDesync=o,this.actionLogger=l,this.netLogger=h,this.debugLogger=c,this.replayRecorder=u,this.debugGameState=d,this.debugGameStateHistory=[],this.queuedRateChanges=[],this.errorState=!1,this.passiveMode=!1,this.receivedActions=new Map,this.receivedNetworkTurn=0,this.lagState=!1,this._onLagStateChange=new EventDispatcher,this._onActionsSent=new EventDispatcher,this._onActionsProcessed=new EventDispatcher,this._onActionsReceived=new EventDispatcher,this.receiveActions=e=>{let t=new DataStream(e);var i=t.readUint32(),e=this.gameoptParser.parseAllPlayerActions(t);this.receivedNetworkTurn=i,this.receivedActions.set(i,e),this._onActionsReceived.dispatch(void 0,i)},this.handleGameDesync=()=>{this.setErrorState(),this.onDesync()}}init(){this.gameTurnMillis=1e3/(this.game.desiredSpeed.value*GameSpeed.BASE_TICKS_PER_SECOND),this.currentNetworkTurn=0,this.currentSubTurn=0,this.gservCon.onGameActions.subscribe(this.receiveActions),this.gservCon.onGameDesync.subscribe(this.handleGameDesync),this.debug("Init: gameTurnMillis = "+this.gameTurnMillis)}canAdvanceNetworkTurn(){return this.currentNetworkTurn<2||this.receivedActions.has(this.currentNetworkTurn-2)}setErrorState(){this.errorState=!0}getErrorState(){return this.errorState}setRate(e){if(this.debug(`Recv rate: ${e.rate} (turn ${e.turnNo})`),0===this.currentSubTurn&&0===this.currentNetworkTurn&&0===e.turnNo)this.updateRate(e.rate);else{if(e.turnNo<this.currentNetworkTurn-2)throw new Error("Rate change has turn number more than two turns in the past.");this.queuedRateChanges.push(e)}}updateRate(e){this.networkTurnMillis=computeNetworkTurnMillis(e,this.gameTurnMillis),this.hashCheckTurnInterval=Math.ceil(LockstepManager.PREFERRED_HASH_CHECK_MILLIS/this.networkTurnMillis),this.netLogger?.debug(`Rate set to ${e} (${this.networkTurnMillis}ms) @ `+this.currentNetworkTurn)}setPassiveMode(e){this.debug("Send passive: "+e),this.passiveMode=e,this.gservCon.sendPlayerActive(!e)}getTurnMillis(){return this.gameTurnMillis}doGameTurn(e){if(!this.errorState){if(!this.networkTurnMillis)throw new Error("Network turn rate should be set by now.");if(this.game.status!==GameStatus.Ended){if(0===this.currentSubTurn){var t=this.queuedRateChanges[0];if(t&&t.turnNo+2===this.currentNetworkTurn&&(this.debug(`Process rate ${t.rate} (turn ${t.turnNo})`),this.updateRate(t.rate),this.queuedRateChanges.shift()),!this.canAdvanceNetworkTurn())return this.handleCommsLag(!0,e),this.debug("Lag state: "+this.lagState),!1;this.debug("Advance turn"),this.commsLagStartTime&&0<e-this.commsLagStartTime&&this.netLogger?.debug(`Waited ${Math.round(e-this.commsLagStartTime)}ms `+"for other clients to catch up."),this.handleCommsLag(!1,e),!this.passiveMode&&this.currentNetworkTurn>=this.receivedNetworkTurn&&this.sendActions(),2<=this.currentNetworkTurn&&(i=this.receivedActions.get(this.currentNetworkTurn-2),this.replayRecorder.recordActions(this.game.currentTick,i),this.processActions(i),this.receivedActions.delete(this.currentNetworkTurn-2),this._onActionsProcessed.dispatch(void 0,this.currentNetworkTurn-2)),this.game.update(),this.passiveMode||this.currentNetworkTurn%this.hashCheckTurnInterval!=0||this.gservCon.sendGameStateHash(this.currentNetworkTurn,this.game.getHash()),this.networkTurnMillis>this.gameTurnMillis?this.currentSubTurn++:this.currentNetworkTurn++}else this.debug("Update"),this.game.update(),this.currentSubTurn++,this.currentSubTurn>=this.networkTurnMillis/this.gameTurnMillis&&(this.currentSubTurn=0,this.currentNetworkTurn++);var i;this.debugGameState&&(i=this.networkTurnMillis/this.gameTurnMillis*this.hashCheckTurnInterval,this.debugGameStateHistory.length>i&&this.debugGameStateHistory.shift(),this.debugGameStateHistory.push(this.game.debugGetState()))}else this.game.update()}}handleCommsLag(e,t){e?(this.commsLagStartTime||(this.commsLagStartTime=t),t-this.commsLagStartTime>LAG_STATE_THRESH_MILLIS&&this.updateLagState(!0)):(this.commsLagStartTime=void 0,this.updateLagState(!1))}updateLagState(e){e!==this.lagState&&(this.lagState=e,this._onLagStateChange.dispatch(void 0,e))}sendActions(){let e=this.inputActions.dequeueAll();e.length||e.push(new NoAction);var t=this.gameoptSerializer.serializePlayerActions(e.map(e=>this.actionSerializer.getActionPayload(e)));this.debug("Send actions: "+t),this.gservCon.sendPlayerActions(this.currentNetworkTurn,t),this._onActionsSent.dispatch(void 0,this.currentNetworkTurn)}processActions(e){[...e].forEach(([i,e])=>e.forEach(e=>{let t=this.actionFactory.create(e.id);t.player=this.game.getPlayer(i),t.unserialize(e.params),t.process();e=t.print();e&&this.actionLogger?.debug(`(${t.player.name})@${this.game.currentTick}: `+e)}))}debug(e){this.debugLogger?.(`${this.currentNetworkTurn}-${this.currentSubTurn}-${this.game.currentTick}: `+e)}dispose(){this.setErrorState(),this.gservCon.onGameActions.unsubscribe(this.receiveActions),this.gservCon.onGameDesync.unsubscribe(this.handleGameDesync)}}LockstepManager.PREFERRED_HASH_CHECK_MILLIS=1e3;const external_perf_hooks_namespaceObject=__WEBPACK_EXTERNAL_createRequire_require("perf_hooks");class AiAnimationLoop{constructor(e){this.gameTurnMgr=e,this.isStarted=!1}start(){this.isStarted||(this.isStarted=!0,this.startTime=void 0,this.lastGameFrame=0)}async waitForTick(){return new Promise((e,t)=>this.doWaitForTick(e,t))}doWaitForTick(e,t){try{this.isStarted||e();var i=external_perf_hooks_namespaceObject.performance.now(),r=this.updateDeltaGameFrames(i);if(0<r)if(!(!1===this.gameTurnMgr.doGameTurn(i)))return void e();setImmediate(()=>this.doWaitForTick(e,t))}catch(e){t(e)}}updateDeltaGameFrames(e){var t=this.gameTurnMgr.getTurnMillis(),i=t!==this.lastGameTurnMillis;this.lastGameTurnMillis=t,i&&(this.lastGameFrame=0,this.startTime=e);let r=0;return this.startTime?(i=e-this.startTime,t=Math.round(i/t),r=t-this.lastGameFrame,this.lastGameFrame=t):this.startTime=e,r}stop(){this.isStarted&&(this.isStarted=!1)}destroy(){this.stop()}}const external_fs_namespaceObject=__WEBPACK_EXTERNAL_createRequire_require("fs");var _GameInstanceApi_bots,_GameInstanceApi_game,_GameInstanceApi_gameApi,_GameInstanceApi_eventsApi,_GameInstanceApi_replay,_GameInstanceApi_turnMgr,_GameInstanceApi_aiAnimationLoop,_GameInstanceApi_onDispose,GameInstanceApi_classPrivateFieldSet=function(e,t,i,r,s){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!s)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!s:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?s.call(e,i):s?s.value=i:t.set(e,i),i},GameInstanceApi_classPrivateFieldGet=function(e,t,i,r){if("a"===i&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?r:"a"===i?r.call(e):r?r.value:t.get(e)};class GameInstanceApi{constructor(e,t,i,r,s,a,n,o,l){_GameInstanceApi_bots.set(this,void 0),_GameInstanceApi_game.set(this,void 0),_GameInstanceApi_gameApi.set(this,void 0),_GameInstanceApi_eventsApi.set(this,void 0),_GameInstanceApi_replay.set(this,void 0),_GameInstanceApi_turnMgr.set(this,void 0),_GameInstanceApi_aiAnimationLoop.set(this,void 0),_GameInstanceApi_onDispose.set(this,void 0),GameInstanceApi_classPrivateFieldSet(this,_GameInstanceApi_bots,e,"f"),GameInstanceApi_classPrivateFieldSet(this,_GameInstanceApi_game,t,"f"),GameInstanceApi_classPrivateFieldSet(this,_GameInstanceApi_gameApi,new GameApi(t,!1),"f"),GameInstanceApi_classPrivateFieldSet(this,_GameInstanceApi_eventsApi,new EventsApi(t.events),"f"),GameInstanceApi_classPrivateFieldSet(this,_GameInstanceApi_replay,i,"f"),GameInstanceApi_classPrivateFieldSet(this,_GameInstanceApi_turnMgr,a,"f"),GameInstanceApi_classPrivateFieldSet(this,_GameInstanceApi_aiAnimationLoop,o,"f"),GameInstanceApi_classPrivateFieldSet(this,_GameInstanceApi_onDispose,l,"f"),GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_eventsApi,"f").subscribe(t=>e.forEach(e=>e.onGameEvent(t,GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_gameApi,"f")))),e.forEach(e=>{e.setContext(new BotContext(GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_gameApi,"f"),new PlayerApi(e.name,GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_gameApi,"f"),new ActionsApi(t,r,s,e,n),new ProductionApi(t.getPlayerByName(e.name).production)),new LoggerApi(AppLogger.get(e.name),GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_gameApi,"f")))),e.onGameInit(GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_gameApi,"f")),e.onGameStart(GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_gameApi,"f"))})}isFinished(){return GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_game,"f").status===GameStatus.Ended||GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_turnMgr,"f").getErrorState()}async update(){if(GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_aiAnimationLoop,"f"))await GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_aiAnimationLoop,"f").waitForTick();else{if(!(GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_turnMgr,"f")instanceof AiPlayTurnManager))throw new Error("Missing animation loop or turn manager");GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_turnMgr,"f").doGameTurn()}GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_bots,"f").forEach(e=>e.onGameTick(GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_gameApi,"f")))}getCurrentTick(){return GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_gameApi,"f").getCurrentTick()}getTickRate(){return GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_gameApi,"f").getTickRate()}getPlayerStats(){return GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_game,"f").getNonNeutralPlayers().filter(e=>!e.isObserver).map(t=>({name:t.name,country:t.country,ai:t.isAi||GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_bots,"f").some(e=>e.name===t.name),defeated:t.defeated,credits:t.credits,startLocation:t.startLocation}))}saveReplay(e){let t=GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_replay,"f");t.finish(GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_game,"f").currentTick);var i=GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_game,"f").gameOpts.mapName+"_"+Date.now()+Replay.extension,r=t.serialize(),i=external_path_namespaceObject.resolve(e??process.cwd(),i);return external_fs_namespaceObject.writeFileSync(i,r,"utf-8"),process.stdout.write(`Replay saved to "${i}"
1
+ import*as __WEBPACK_EXTERNAL_MODULE_three__ from"three";import*as __WEBPACK_EXTERNAL_MODULE_fetch_blob_71f8024a__ from"fetch-blob";import*as __WEBPACK_EXTERNAL_MODULE_websocket_polyfill_8396782d__ from"websocket-polyfill";import{createRequire as __WEBPACK_EXTERNAL_createRequire}from"node:module";const __WEBPACK_EXTERNAL_createRequire_require=__WEBPACK_EXTERNAL_createRequire(import.meta.url);import*as __WEBPACK_EXTERNAL_MODULE_es_dirname_044d89a0__ from"es-dirname";import*as __WEBPACK_EXTERNAL_MODULE_file_system_access_58c08c7f__ from"file-system-access";import*as __WEBPACK_EXTERNAL_MODULE_file_system_access_lib_adapters_node_js_b1c03fd5__ from"file-system-access/lib/adapters/node.js";var __webpack_modules__={70(e){e.exports=__WEBPACK_EXTERNAL_MODULE_three__},370(l,h,c){var d;!function(){"use strict";function e(e,t){return function(){return t.apply(e,arguments)}}function i(){for(var e,t=arguments,i=t[0],r=1;r<t.length;r++)for(e in t[r])e in i||!t[r].hasOwnProperty(e)||(i[e]=t[r][e]);return i}var r,o={VERSION:"1.4.1"},s={},t=function(e,t){return{value:e,name:t}};o.DEBUG=t(1,"DEBUG"),o.INFO=t(2,"INFO"),o.TIME=t(3,"TIME"),o.WARN=t(4,"WARN"),o.ERROR=t(8,"ERROR"),o.OFF=t(99,"OFF");function a(e){this.context=e,this.setLevel(e.filterLevel),this.log=this.info}a.prototype={setLevel:function(e){e&&"value"in e&&(this.context.filterLevel=e)},getLevel:function(){return this.context.filterLevel},enabledFor:function(e){var t=this.context.filterLevel;return e.value>=t.value},debug:function(){this.invoke(o.DEBUG,arguments)},info:function(){this.invoke(o.INFO,arguments)},warn:function(){this.invoke(o.WARN,arguments)},error:function(){this.invoke(o.ERROR,arguments)},time:function(e){"string"==typeof e&&0<e.length&&this.invoke(o.TIME,[e,"start"])},timeEnd:function(e){"string"==typeof e&&0<e.length&&this.invoke(o.TIME,[e,"end"])},invoke:function(e,t){r&&this.enabledFor(e)&&r(t,i({level:e},this.context))}};var n=new a({filterLevel:o.OFF});(t=o).enabledFor=e(n,n.enabledFor),t.debug=e(n,n.debug),t.time=e(n,n.time),t.timeEnd=e(n,n.timeEnd),t.info=e(n,n.info),t.warn=e(n,n.warn),t.error=e(n,n.error),t.log=t.info,o.setHandler=function(e){r=e},o.setLevel=function(e){for(var t in n.setLevel(e),s)s.hasOwnProperty(t)&&s[t].setLevel(e)},o.getLevel=function(){return n.getLevel()},o.get=function(e){return s[e]||(s[e]=new a(i({name:e},n.context)))},o.createDefaultHandler=function(s){(s=s||{}).formatter=s.formatter||function(e,t){t.name&&e.unshift("["+t.name+"]")};function a(e,t){Function.prototype.apply.call(e,console,t)}var n={};return"undefined"==typeof console?function(){}:function(e,t){e=Array.prototype.slice.call(e);var i,r=console.log;t.level===o.TIME?(i=(t.name?"["+t.name+"] ":"")+e[0],"start"===e[1]?console.time?console.time(i):n[i]=(new Date).getTime():console.timeEnd?console.timeEnd(i):a(r,[i+": "+((new Date).getTime()-n[i])+"ms"])):(t.level===o.WARN&&console.warn?r=console.warn:t.level===o.ERROR&&console.error?r=console.error:t.level===o.INFO&&console.info?r=console.info:t.level===o.DEBUG&&console.debug&&(r=console.debug),s.formatter(e,t),a(r,e))}},o.useDefaults=function(e){o.setLevel(e&&e.defaultLevel||o.DEBUG),o.setHandler(o.createDefaultHandler(e))},void 0===(d="function"==typeof(d=o)?d.call(h,c,h,l):d)||(l.exports=d)}()},422(e){e.exports=__WEBPACK_EXTERNAL_MODULE_fetch_blob_71f8024a__},804(e){function t(e){null==e&&(e=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,e.constructor==Array?this.init_by_array(e,e.length):this.init_seed(e)}t.prototype.init_seed=function(e){for(this.mt[0]=e>>>0,this.mti=1;this.mti<this.N;this.mti++){e=this.mt[this.mti-1]^this.mt[this.mti-1]>>>30;this.mt[this.mti]=(1812433253*((4294901760&e)>>>16)<<16)+1812433253*(65535&e)+this.mti,this.mt[this.mti]>>>=0}},t.prototype.init_by_array=function(e,t){var i,r,s;for(this.init_seed(19650218),i=1,r=0,s=this.N>t?this.N:t;s;s--){var a=this.mt[i-1]^this.mt[i-1]>>>30;this.mt[i]=(this.mt[i]^(1664525*((4294901760&a)>>>16)<<16)+1664525*(65535&a))+e[r]+r,this.mt[i]>>>=0,r++,++i>=this.N&&(this.mt[0]=this.mt[this.N-1],i=1),t<=r&&(r=0)}for(s=this.N-1;s;s--){a=this.mt[i-1]^this.mt[i-1]>>>30;this.mt[i]=(this.mt[i]^(1566083941*((4294901760&a)>>>16)<<16)+1566083941*(65535&a))-i,this.mt[i]>>>=0,++i>=this.N&&(this.mt[0]=this.mt[this.N-1],i=1)}this.mt[0]=2147483648},t.prototype.random_int=function(){var e,t,i=new Array(0,this.MATRIX_A);if(this.mti>=this.N){for(this.mti==this.N+1&&this.init_seed(5489),t=0;t<this.N-this.M;t++)e=this.mt[t]&this.UPPER_MASK|this.mt[t+1]&this.LOWER_MASK,this.mt[t]=this.mt[t+this.M]^e>>>1^i[1&e];for(;t<this.N-1;t++)e=this.mt[t]&this.UPPER_MASK|this.mt[t+1]&this.LOWER_MASK,this.mt[t]=this.mt[t+(this.M-this.N)]^e>>>1^i[1&e];e=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^e>>>1^i[1&e],this.mti=0}return e=this.mt[this.mti++],e^=e>>>11,e^=e<<7&2636928640,e^=e<<15&4022730752,(e^=e>>>18)>>>0},t.prototype.random_int31=function(){return this.random_int()>>>1},t.prototype.random_incl=function(){return this.random_int()*(1/4294967295)},t.prototype.random=function(){return this.random_int()*(1/4294967296)},t.prototype.random_excl=function(){return(this.random_int()+.5)*(1/4294967296)},t.prototype.random_long=function(){return 1/9007199254740992*(67108864*(this.random_int()>>>5)+(this.random_int()>>>6))},e.exports=t},887(e,t,i){i.r(t),i.d(t,{default:()=>r});const r=function(){"use strict";var i=new function(){this.blockSize=131072,this.minNewSize=this.blockSize,this.maxSize=0,this.OK=0,this.INPUT_OVERRUN=-4,this.OUTPUT_OVERRUN=-5,this.LOOKBEHIND_OVERRUN=-6,this.EOF_FOUND=-999,this.ret=0,this.buf=null,this.buf32=null,this.out=new Uint8Array(262144),this.cbl=0,this.ip_end=0,this.op_end=0,this.t=0,this.ip=0,this.op=0,this.m_pos=0,this.m_len=0,this.m_off=0,this.dv_hi=0,this.dv_lo=0,this.dindex=0,this.ii=0,this.jj=0,this.tt=0,this.v=0,this.dict=new Uint32Array(16384),this.emptyDict=new Uint32Array(16384),this.skipToFirstLiteralFun=!1,this.returnNewBuffers=!0,this.setBlockSize=function(e){return"number"==typeof e&&!isNaN(e)&&0<parseInt(e)&&(this.blockSize=parseInt(e),!0)},this.setOutputSize=function(e){return"number"==typeof e&&!isNaN(e)&&0<parseInt(e)&&(this.out=new Uint8Array(parseInt(e)),!0)},this.setReturnNewBuffers=function(e){this.returnNewBuffers=!!e},this.applyConfig=function(e){void 0!==e&&(void 0!==e.outputSize&&i.setOutputSize(e.outputSize),void 0!==e.blockSize&&i.setBlockSize(e.blockSize))},this.ctzl=function(e){var t;return 1&e?t=0:(t=1,0==(65535&e)&&(e>>=16,t+=16),0==(255&e)&&(e>>=8,t+=8),0==(15&e)&&(e>>=4,t+=4),0==(3&e)&&(e>>=2,t+=2),t-=1&e),t},this.extendBuffer=function(){var e=new Uint8Array(this.minNewSize+(this.blockSize-this.minNewSize%this.blockSize));e.set(this.out),this.out=e,this.cbl=this.out.length},this.match_next=function(){this.minNewSize=this.op+3,this.minNewSize>this.cbl&&this.extendBuffer(),this.out[this.op++]=this.buf[this.ip++],1<this.t&&(this.out[this.op++]=this.buf[this.ip++],2<this.t&&(this.out[this.op++]=this.buf[this.ip++])),this.t=this.buf[this.ip++]},this.match_done=function(){return this.t=3&this.buf[this.ip-2],this.t},this.copy_match=function(){for(this.t+=2,this.minNewSize=this.op+this.t,this.minNewSize>this.cbl&&this.extendBuffer();this.out[this.op++]=this.out[this.m_pos++],0<--this.t;);},this.copy_from_buf=function(){for(this.minNewSize=this.op+this.t,this.minNewSize>this.cbl&&this.extendBuffer();this.out[this.op++]=this.buf[this.ip++],0<--this.t;);},this.match=function(){for(;;){if(64<=this.t)this.m_pos=this.op-1-(this.t>>2&7)-(this.buf[this.ip++]<<3),this.t=(this.t>>5)-1,this.copy_match();else if(32<=this.t){if(this.t&=31,0===this.t){for(;0===this.buf[this.ip];)this.t+=255,this.ip++;this.t+=31+this.buf[this.ip++]}this.m_pos=this.op-1-(this.buf[this.ip]>>2)-(this.buf[this.ip+1]<<6),this.ip+=2,this.copy_match()}else if(16<=this.t){if(this.m_pos=this.op-((8&this.t)<<11),this.t&=7,0===this.t){for(;0===this.buf[this.ip];)this.t+=255,this.ip++;this.t+=7+this.buf[this.ip++]}if(this.m_pos-=(this.buf[this.ip]>>2)+(this.buf[this.ip+1]<<6),this.ip+=2,this.m_pos===this.op)return this.state.outputBuffer=!0===this.returnNewBuffers?new Uint8Array(this.out.subarray(0,this.op)):this.out.subarray(0,this.op),this.EOF_FOUND;this.m_pos-=16384,this.copy_match()}else this.m_pos=this.op-1-(this.t>>2)-(this.buf[this.ip++]<<2),this.minNewSize=this.op+2,this.minNewSize>this.cbl&&this.extendBuffer(),this.out[this.op++]=this.out[this.m_pos++],this.out[this.op++]=this.out[this.m_pos];if(0===this.match_done())return this.OK;this.match_next()}},this.decompress=function(e){if(this.state=e,this.buf=this.state.inputBuffer,this.cbl=this.out.length,this.ip_end=this.buf.length,this.t=0,this.ip=0,this.op=0,this.m_pos=0,this.skipToFirstLiteralFun=!1,17<this.buf[this.ip])if(this.t=this.buf[this.ip++]-17,this.t<4){if(this.match_next(),this.ret=this.match(),this.ret!==this.OK)return this.ret===this.EOF_FOUND?this.OK:this.ret}else this.copy_from_buf(),this.skipToFirstLiteralFun=!0;for(;;){if(this.skipToFirstLiteralFun)this.skipToFirstLiteralFun=!1;else{if(this.t=this.buf[this.ip++],16<=this.t){if(this.ret=this.match(),this.ret!==this.OK)return this.ret===this.EOF_FOUND?this.OK:this.ret;continue}if(0===this.t){for(;0===this.buf[this.ip];)this.t+=255,this.ip++;this.t+=15+this.buf[this.ip++]}this.t+=3,this.copy_from_buf()}if(this.t=this.buf[this.ip++],this.t<16){if(this.m_pos=this.op-2049,this.m_pos-=this.t>>2,this.m_pos-=this.buf[this.ip++]<<2,this.minNewSize=this.op+3,this.minNewSize>this.cbl&&this.extendBuffer(),this.out[this.op++]=this.out[this.m_pos++],this.out[this.op++]=this.out[this.m_pos++],this.out[this.op++]=this.out[this.m_pos],0===this.match_done())continue;this.match_next()}if(this.ret=this.match(),this.ret!==this.OK)return this.ret===this.EOF_FOUND?this.OK:this.ret}return this.OK},this._compressCore=function(){for(this.ip_start=this.ip,this.ip_end=this.ip+this.ll-20,this.jj=this.ip,this.ti=this.t,this.ip+=this.ti<4?4-this.ti:0,this.ip+=1+(this.ip-this.jj>>5);!(this.ip>=this.ip_end);)if(this.dv_lo=this.buf[this.ip]|this.buf[this.ip+1]<<8,this.dv_hi=this.buf[this.ip+2]|this.buf[this.ip+3]<<8,this.dindex=((17053*this.dv_lo>>>16)+17053*this.dv_hi+6180*this.dv_lo&65535)>>>2,this.m_pos=this.ip_start+this.dict[this.dindex],this.dict[this.dindex]=this.ip-this.ip_start,(this.dv_hi<<16)+this.dv_lo==(this.buf[this.m_pos]|this.buf[this.m_pos+1]<<8|this.buf[this.m_pos+2]<<16|this.buf[this.m_pos+3]<<24)){if(this.jj-=this.ti,this.ti=0,this.v=this.ip-this.jj,0!==this.v)if(this.v<=3)for(this.out[this.op-2]|=this.v;this.out[this.op++]=this.buf[this.jj++],0<--this.v;);else{if(this.v<=18)this.out[this.op++]=this.v-3;else{for(this.tt=this.v-18,this.out[this.op++]=0;255<this.tt;)this.tt-=255,this.out[this.op++]=0;this.out[this.op++]=this.tt}for(;this.out[this.op++]=this.buf[this.jj++],0<--this.v;);}if(this.m_len=4,this.buf[this.ip+this.m_len]===this.buf[this.m_pos+this.m_len])for(;this.m_len+=1,this.buf[this.ip+this.m_len]===this.buf[this.m_pos+this.m_len]&&(this.m_len+=1,this.buf[this.ip+this.m_len]===this.buf[this.m_pos+this.m_len]&&(this.m_len+=1,this.buf[this.ip+this.m_len]===this.buf[this.m_pos+this.m_len]&&(this.m_len+=1,this.buf[this.ip+this.m_len]===this.buf[this.m_pos+this.m_len]&&(this.m_len+=1,this.buf[this.ip+this.m_len]===this.buf[this.m_pos+this.m_len]&&(this.m_len+=1,this.buf[this.ip+this.m_len]===this.buf[this.m_pos+this.m_len]&&(this.m_len+=1,this.buf[this.ip+this.m_len]===this.buf[this.m_pos+this.m_len]&&(this.m_len+=1,this.buf[this.ip+this.m_len]===this.buf[this.m_pos+this.m_len]&&!(this.ip+this.m_len>=this.ip_end)&&this.buf[this.ip+this.m_len]===this.buf[this.m_pos+this.m_len]))))))););if(this.m_off=this.ip-this.m_pos,this.ip+=this.m_len,this.jj=this.ip,this.m_len<=8&&this.m_off<=2048)--this.m_off,this.out[this.op++]=this.m_len-1<<5|(7&this.m_off)<<2,this.out[this.op++]=this.m_off>>3;else if(this.m_off<=16384){if(--this.m_off,this.m_len<=33)this.out[this.op++]=32|this.m_len-2;else{for(this.m_len-=33,this.out[this.op++]=32;255<this.m_len;)this.m_len-=255,this.out[this.op++]=0;this.out[this.op++]=this.m_len}this.out[this.op++]=this.m_off<<2,this.out[this.op++]=this.m_off>>6}else{if(this.m_off-=16384,this.m_len<=9)this.out[this.op++]=16|this.m_off>>11&8|this.m_len-2;else{for(this.m_len-=9,this.out[this.op++]=16|this.m_off>>11&8;255<this.m_len;)this.m_len-=255,this.out[this.op++]=0;this.out[this.op++]=this.m_len}this.out[this.op++]=this.m_off<<2,this.out[this.op++]=this.m_off>>6}}else this.ip+=1+(this.ip-this.jj>>5);this.t=this.ll-(this.jj-this.ip_start-this.ti)},this.compress=function(e){for(this.state=e,this.ip=0,this.buf=this.state.inputBuffer,this.maxSize=this.buf.length+Math.ceil(this.buf.length/16)+64+3,this.maxSize>this.out.length&&(this.out=new Uint8Array(this.maxSize)),this.op=0,this.l=this.buf.length,this.t=0;20<this.l&&(this.ll=this.l<=49152?this.l:49152,!(this.t+this.ll>>5<=0));)this.dict.set(this.emptyDict),this.prev_ip=this.ip,this._compressCore(),this.ip=this.prev_ip+this.ll,this.l-=this.ll;if(this.t+=this.l,0<this.t){if(this.ii=this.buf.length-this.t,0===this.op&&this.t<=238)this.out[this.op++]=17+this.t;else if(this.t<=3)this.out[this.op-2]|=this.t;else if(this.t<=18)this.out[this.op++]=this.t-3;else{for(this.tt=this.t-18,this.out[this.op++]=0;255<this.tt;)this.tt-=255,this.out[this.op++]=0;this.out[this.op++]=this.tt}for(;this.out[this.op++]=this.buf[this.ii++],0<--this.t;);}return this.out[this.op++]=17,this.out[this.op++]=0,this.out[this.op++]=0,this.state.outputBuffer=!0===this.returnNewBuffers?new Uint8Array(this.out.subarray(0,this.op)):this.out.subarray(0,this.op),this.OK}};return{setBlockSize:function(e){return i.setBlockSize(e)},setOutputEstimate:function(e){return i.setOutputSize(e)},setReturnNewBuffers:function(e){i.setReturnNewBuffers(e)},compress:function(e,t){return void 0!==t&&i.applyConfig(t),i.compress(e)},decompress:function(e,t){return void 0!==t&&i.applyConfig(t),i.decompress(e)}}}()}},__webpack_module_cache__={};function __webpack_require__(e){var t=__webpack_module_cache__[e];if(void 0!==t)return t.exports;t=__webpack_module_cache__[e]={exports:{}};return __webpack_modules__[e].call(t.exports,t,t.exports,__webpack_require__),t.exports}__webpack_require__.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return __webpack_require__.d(t,{a:t}),t},__webpack_require__.d=(e,t)=>{for(var i in t)__webpack_require__.o(t,i)&&!__webpack_require__.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var __webpack_exports__={};__webpack_require__.r(__webpack_exports__);const external_websocket_polyfill_namespaceObject=__WEBPACK_EXTERNAL_MODULE_websocket_polyfill_8396782d__,external_node_crypto_namespaceObject=__WEBPACK_EXTERNAL_createRequire_require("node:crypto"),external_path_namespaceObject=__WEBPACK_EXTERNAL_createRequire_require("path"),external_es_dirname_namespaceObject=__WEBPACK_EXTERNAL_MODULE_es_dirname_044d89a0__,external_file_system_access_namespaceObject=__WEBPACK_EXTERNAL_MODULE_file_system_access_58c08c7f__,node_js_namespaceObject=__WEBPACK_EXTERNAL_MODULE_file_system_access_lib_adapters_node_js_b1c03fd5__;class IniSection{constructor(e){this.entries=new Map,this.sections=new Map,this.name=e}fromJson(e){for(var t in e){var i;e.hasOwnProperty(t)&&(i=e[t],Array.isArray(i)||"object"!=typeof i?this.set(t,i):this.sections.set(t,new IniSection(t).fromJson(i)))}return this}clone(){let i=new IniSection(this.name);return this.entries.forEach((e,t)=>{i.set(t,e)}),this.sections.forEach((e,t)=>{i.sections.set(t,e.clone())}),i}set(e,t){this.entries.set(e,t)}get(e){return this.entries.get(e)}has(e){return this.entries.has(e)}getString(e,t=""){e=this.get(e);return e&&"string"==typeof e?e:t}getNumber(e,t=0){var i=this.get(e);if(!i||"string"!=typeof i)return t;var r=this.parseNumber(i);return void 0===r?(console.warn(`Invalid value for key ${e}. "${i}" is not a valid number or percentage string.`),t):r}parseNumber(e){let t;if(t=e.match(/%$/)?Number(e.replace("%",""))/100:Number(e),!isNaN(t))return t}getFixed(e,t=0){return this.toFixedPointPrecision(this.getNumber(e,t))}toFixedPointPrecision(e){return(65536*e|0)/65536}getBool(e,t=!1){let i=this.getString(e).trim();return i=i&&i.toLowerCase(),!(!i||-1===["yes","1","true","on"].indexOf(i))||(!i||-1===["no","0","false","off"].indexOf(i))&&t}getKeyArray(e,t=[]){e=this.get(e);return e&&Array.isArray(e)?e:t}getArray(e,t=/,\s*/,i=[]){let r=this.getString(e).trim();return r=r.replace(/,$/,"").replace(/,+/g,","),r?r.split(t):i}getNumberArray(e,t=/,\s*/,i=[]){let r=this.getString(e).trim();if(!r)return i;let s=[];for(var a of r.split(t)){if(!a)return i;var n=this.parseNumber(a);if(void 0===n)return console.warn(`Invalid value for key ${e}. "${a}" is not a valid number or percentage string.`),i;s.push(n)}return s}getFixedArray(e,t=/,\s*/,i=[]){return this.getNumberArray(e,t,i).map(e=>this.toFixedPointPrecision(e))}getEnum(e,t,i,r=!1){let s=this.getString(e).trim();if(!s)return i;let a;if(r){let e=Object.getOwnPropertyNames(t);r=e.find(e=>e.toLowerCase()===s.toLowerCase());r&&(a=t[r])}else t.hasOwnProperty(s)&&(a=t[s]);return void 0===a?(console.warn(`Invalid value for key "${e}". "${s}" is not an accepted enum value.`),i):a}getEnumNumeric(e,t,i){var r=this.getString(e).trim();if(!r)return i;let s;return Number.isInteger(parseInt(r,10))&&t.hasOwnProperty(r)&&(s=parseInt(r,10)),void 0===s?(console.warn(`Invalid value for key "${e}". "${r}" is not an accepted enum value.`),i):s}getEnumArray(e,r,t=/,\s*/,s=[],a=!1){let n=this.getString(e).trim();if(!n)return s;let o=[];for(let i of n.split(t)){if(!i)return s;let t=!1;if(a){let e=Object.getOwnPropertyNames(r);var l=e.find(e=>e.toLowerCase()===i.toLowerCase());l&&(o.push(r[l]),t=!0)}else r.hasOwnProperty(i)&&(o.push(r[i]),t=!0);if(!t)return console.warn(`Invalid value "${i}" for key "${e}".`),s}return o}getHighestNumericIndex(){let i=0,r;return this.entries.forEach((e,t)=>{r=parseInt(t,10),r>i&&(i=r)}),i}isNumericIndexArray(){return 0<this.getHighestNumericIndex()||this.has("0")}getConcatenatedValues(){let e="";for(var t of this.entries.values())"string"==typeof t&&(e+=t);return e}toString(e){let t=[],i=(e?e+".":"")+this.name;t.push(`[${i}]`);for(var[r,s]of this.entries)if(Array.isArray(s))for(var a of s)t.push(r+"[]="+a);else t.push(r+"="+s);return t.push(""),t.join("\r\n")+[...this.sections.values()].map(e=>e.toString(i)).join("\r\n")}mergeWith(e){if(this.isNumericIndexArray()){let i=this.getHighestNumericIndex()+1;e.entries.forEach((e,t)=>{Number.isNaN(Number(t))||Array.isArray(e)||this.set((i++).toString(),e)})}else e.entries.forEach((e,t)=>{this.set(t,Array.isArray(e)?[...e]:e)});e.sections.forEach((e,t)=>{let i=this.getOrCreateSection(t);i.mergeWith(e)})}getOrCreateSection(e){let t=this.sections.get(e);return t||(t=new IniSection(e),this.sections.set(e,t)),t}getSection(e){return this.sections.get(e)}getOrderedSections(){return[...this.sections.values()]}}class IniParser{parse(e){let a={},i=a,r,s=/^\[([^\]]*)\]\s*$|^([^=]+)(=(.*))?$/i,t=e.split(/[\r\n]+/g);return t.forEach(t=>{if(t&&!t.match(/^\s*[;#]/)){t=(t=t.replace(/]\s*(\/\/|;|#).*$/,"]")).match(s);if(t){if(void 0!==t[1])return r=this.unsafe(t[1]),void(i=a[r]=a[r]||{});let e=this.unsafe(t[2]);t=t[3]?this.unsafe(t[4]||""):"";2<e.length&&"[]"===e.slice(-2)&&(e=e.substring(0,e.length-2),i[e]?Array.isArray(i[e])||(i[e]=[i[e]]):i[e]=[]),Array.isArray(i[e])?i[e].push(t):i[e]=t}}}),Object.keys(a).filter(e=>{if(!a[e]||"object"!=typeof a[e]||Array.isArray(a[e]))return!1;let t=this.dotSplit(e),i=a,r=t.pop();var s=r.replace(/\\\./g,".");return t.forEach(function(e){i[e]&&"object"==typeof i[e]||(i[e]={}),i=i[e]}),(i!==a||s!==r)&&(i[s]=a[e],!0)}).forEach(function(e){delete a[e]}),a}dotSplit(e){return e.replace(/\x01/g,"LITERAL\\1LITERAL").replace(/\\\./g,"").split(/\./).map(e=>e.replace(/\x01/g,"\\.").replace(/\x02LITERAL\\1LITERAL\x02/g,""))}isQuoted(e){return'"'===e.charAt(0)&&'"'===e.slice(-1)||"'"===e.charAt(0)&&"'"===e.slice(-1)}unsafe(s){if(s=(s||"").trim(),this.isQuoted(s))return s=s.substr(1,s.length-2);{let i=!1,r="";for(let e=0,t=s.length;e<t;e++){var a=s.charAt(e);if(i)-1!=="\\;#".indexOf(a)?r+=a:r+="\\"+a,i=!1;else{if(-1!==";#".indexOf(a))break;"\\"===a?i=!0:r+=a}}return i&&(r+="\\"),r=r.trim(),r}}}class DataStream{constructor(e,t,i=DataStream.LITTLE_ENDIAN){this.endianness=i,this.position=0,this._dynamicSize=!0,this._byteLength=0,this._byteOffset=t||0,e instanceof ArrayBuffer?this.buffer=e:"object"==typeof e?(this.dataView=e,t&&(this._byteOffset+=t)):this.buffer=new ArrayBuffer(e||0)}get dynamicSize(){return this._dynamicSize}set dynamicSize(e){e||this._trimAlloc(),this._dynamicSize=e}get byteLength(){return this._byteLength-this._byteOffset}get buffer(){return this._trimAlloc(),this._buffer}set buffer(e){this._buffer=e,this._dataView=new DataView(this._buffer,this._byteOffset),this._byteLength=this._buffer.byteLength}get byteOffset(){return this._byteOffset}set byteOffset(e){this._byteOffset=e,this._dataView=new DataView(this._buffer,this._byteOffset),this._byteLength=this._buffer.byteLength}get dataView(){return this._dataView}set dataView(e){this._byteOffset=e.byteOffset,this._buffer=e.buffer,this._dataView=new DataView(this._buffer,this._byteOffset),this._byteLength=this._byteOffset+e.byteLength}bigEndian(){return this.endianness=DataStream.BIG_ENDIAN,this}_realloc(t){if(this._dynamicSize){var i=this._byteOffset+this.position+t;let e=this._buffer.byteLength;if(i<=e)i>this._byteLength&&(this._byteLength=i);else{for(e<1&&(e=1);i>e;)e*=2;var r=new ArrayBuffer(e),t=new Uint8Array(this._buffer);const s=new Uint8Array(r,0,t.length);s.set(t),this.buffer=r,this._byteLength=i}}}_trimAlloc(){if(this._byteLength!==this._buffer.byteLength){var e=new ArrayBuffer(this._byteLength);const i=new Uint8Array(e);var t=new Uint8Array(this._buffer,0,i.length);i.set(t),this.buffer=e}}seek(e){e=Math.max(0,Math.min(this.byteLength,e));this.position=isNaN(e)||!isFinite(e)?0:e}isEof(){return this.position>=this.byteLength}mapInt32Array(e,t){this._realloc(4*e);var i=new Int32Array(this._buffer,this.byteOffset+this.position,e);return DataStream.arrayToNative(i,void 0===t?this.endianness:t),this.position+=4*e,i}mapInt16Array(e,t){this._realloc(2*e);var i=new Int16Array(this._buffer,this.byteOffset+this.position,e);return DataStream.arrayToNative(i,void 0===t?this.endianness:t),this.position+=2*e,i}mapInt8Array(e){this._realloc(e);var t=new Int8Array(this._buffer,this.byteOffset+this.position,e);return this.position+=e,t}mapUint32Array(e,t){this._realloc(4*e);var i=new Uint32Array(this._buffer,this.byteOffset+this.position,e);return DataStream.arrayToNative(i,void 0===t?this.endianness:t),this.position+=4*e,i}mapUint16Array(e,t){this._realloc(2*e);var i=new Uint16Array(this._buffer,this.byteOffset+this.position,e);return DataStream.arrayToNative(i,void 0===t?this.endianness:t),this.position+=2*e,i}mapUint8Array(e){this._realloc(e);var t=new Uint8Array(this._buffer,this.byteOffset+this.position,e);return this.position+=e,t}mapFloat64Array(e,t){this._realloc(8*e);var i=new Float64Array(this._buffer,this.byteOffset+this.position,e);return DataStream.arrayToNative(i,void 0===t?this.endianness:t),this.position+=8*e,i}mapFloat32Array(e,t){this._realloc(4*e);var i=new Float32Array(this._buffer,this.byteOffset+this.position,e);return DataStream.arrayToNative(i,void 0===t?this.endianness:t),this.position+=4*e,i}readInt32Array(e,t){e=void 0===e?this.byteLength-this.position/4:e;var i=new Int32Array(e);return DataStream.memcpy(i.buffer,0,this.buffer,this.byteOffset+this.position,e*i.BYTES_PER_ELEMENT),DataStream.arrayToNative(i,void 0===t?this.endianness:t),this.position+=i.byteLength,i}readInt16Array(e,t){e=void 0===e?this.byteLength-this.position/2:e;var i=new Int16Array(e);return DataStream.memcpy(i.buffer,0,this.buffer,this.byteOffset+this.position,e*i.BYTES_PER_ELEMENT),DataStream.arrayToNative(i,void 0===t?this.endianness:t),this.position+=i.byteLength,i}readInt8Array(e){e=void 0===e?this.byteLength-this.position:e;var t=new Int8Array(e);return DataStream.memcpy(t.buffer,0,this.buffer,this.byteOffset+this.position,e*t.BYTES_PER_ELEMENT),this.position+=t.byteLength,t}readUint32Array(e,t){e=void 0===e?this.byteLength-this.position/4:e;var i=new Uint32Array(e);return DataStream.memcpy(i.buffer,0,this.buffer,this.byteOffset+this.position,e*i.BYTES_PER_ELEMENT),DataStream.arrayToNative(i,void 0===t?this.endianness:t),this.position+=i.byteLength,i}readUint16Array(e,t){e=void 0===e?this.byteLength-this.position/2:e;var i=new Uint16Array(e);return DataStream.memcpy(i.buffer,0,this.buffer,this.byteOffset+this.position,e*i.BYTES_PER_ELEMENT),DataStream.arrayToNative(i,void 0===t?this.endianness:t),this.position+=i.byteLength,i}readUint8Array(e){e=void 0===e?this.byteLength-this.position:e;var t=new Uint8Array(e);return DataStream.memcpy(t.buffer,0,this.buffer,this.byteOffset+this.position,e*t.BYTES_PER_ELEMENT),this.position+=t.byteLength,t}readFloat64Array(e,t){e=void 0===e?this.byteLength-this.position/8:e;var i=new Float64Array(e);return DataStream.memcpy(i.buffer,0,this.buffer,this.byteOffset+this.position,e*i.BYTES_PER_ELEMENT),DataStream.arrayToNative(i,void 0===t?this.endianness:t),this.position+=i.byteLength,i}readFloat32Array(e,t){e=void 0===e?this.byteLength-this.position/4:e;var i=new Float32Array(e);return DataStream.memcpy(i.buffer,0,this.buffer,this.byteOffset+this.position,e*i.BYTES_PER_ELEMENT),DataStream.arrayToNative(i,void 0===t?this.endianness:t),this.position+=i.byteLength,i}writeInt32Array(t,i){if(this._realloc(4*t.length),t instanceof Int32Array&&(this.byteOffset+this.position)%t.BYTES_PER_ELEMENT==0)DataStream.memcpy(this._buffer,this.byteOffset+this.position,t.buffer,t.byteOffset,t.byteLength),this.mapInt32Array(t.length,i);else for(let e=0;e<t.length;e++)this.writeInt32(t[e],i);return this}writeInt16Array(t,i){if(this._realloc(2*t.length),t instanceof Int16Array&&(this.byteOffset+this.position)%t.BYTES_PER_ELEMENT==0)DataStream.memcpy(this._buffer,this.byteOffset+this.position,t.buffer,t.byteOffset,t.byteLength),this.mapInt16Array(t.length,i);else for(let e=0;e<t.length;e++)this.writeInt16(t[e],i);return this}writeInt8Array(t){if(this._realloc(t.length),t instanceof Int8Array&&(this.byteOffset+this.position)%t.BYTES_PER_ELEMENT==0)DataStream.memcpy(this._buffer,this.byteOffset+this.position,t.buffer,t.byteOffset,t.byteLength),this.mapInt8Array(t.length);else for(let e=0;e<t.length;e++)this.writeInt8(t[e]);return this}writeUint32Array(t,i){if(this._realloc(4*t.length),t instanceof Uint32Array&&(this.byteOffset+this.position)%t.BYTES_PER_ELEMENT==0)DataStream.memcpy(this._buffer,this.byteOffset+this.position,t.buffer,t.byteOffset,t.byteLength),this.mapUint32Array(t.length,i);else for(let e=0;e<t.length;e++)this.writeUint32(t[e],i);return this}writeUint16Array(t,i){if(this._realloc(2*t.length),t instanceof Uint16Array&&(this.byteOffset+this.position)%t.BYTES_PER_ELEMENT==0)DataStream.memcpy(this._buffer,this.byteOffset+this.position,t.buffer,t.byteOffset,t.byteLength),this.mapUint16Array(t.length,i);else for(let e=0;e<t.length;e++)this.writeUint16(t[e],i);return this}writeUint8Array(t){if(this._realloc(t.length),t instanceof Uint8Array&&(this.byteOffset+this.position)%t.BYTES_PER_ELEMENT==0)DataStream.memcpy(this._buffer,this.byteOffset+this.position,t.buffer,t.byteOffset,t.byteLength),this.mapUint8Array(t.length);else for(let e=0;e<t.length;e++)this.writeUint8(t[e]);return this}writeFloat64Array(t,i){if(this._realloc(8*t.length),t instanceof Float64Array&&(this.byteOffset+this.position)%t.BYTES_PER_ELEMENT==0)DataStream.memcpy(this._buffer,this.byteOffset+this.position,t.buffer,t.byteOffset,t.byteLength),this.mapFloat64Array(t.length,i);else for(let e=0;e<t.length;e++)this.writeFloat64(t[e],i);return this}writeFloat32Array(t,i){if(this._realloc(4*t.length),t instanceof Float32Array&&(this.byteOffset+this.position)%t.BYTES_PER_ELEMENT==0)DataStream.memcpy(this._buffer,this.byteOffset+this.position,t.buffer,t.byteOffset,t.byteLength),this.mapFloat32Array(t.length,i);else for(let e=0;e<t.length;e++)this.writeFloat32(t[e],i);return this}readInt32(e){e=this._dataView.getInt32(this.position,void 0===e?this.endianness:e);return this.position+=4,e}readInt16(e){e=this._dataView.getInt16(this.position,void 0===e?this.endianness:e);return this.position+=2,e}readInt8(){var e=this._dataView.getInt8(this.position);return this.position+=1,e}readUint32(e){e=this._dataView.getUint32(this.position,void 0===e?this.endianness:e);return this.position+=4,e}readUint16(e){e=this._dataView.getUint16(this.position,void 0===e?this.endianness:e);return this.position+=2,e}readUint8(){var e=this._dataView.getUint8(this.position);return this.position+=1,e}readFloat32(e){e=this._dataView.getFloat32(this.position,void 0===e?this.endianness:e);return this.position+=4,e}readFloat64(e){e=this._dataView.getFloat64(this.position,void 0===e?this.endianness:e);return this.position+=8,e}writeInt32(e,t){return this._realloc(4),this._dataView.setInt32(this.position,e,void 0===t?this.endianness:t),this.position+=4,this}writeInt16(e,t){return this._realloc(2),this._dataView.setInt16(this.position,e,void 0===t?this.endianness:t),this.position+=2,this}writeInt8(e){return this._realloc(1),this._dataView.setInt8(this.position,e),this.position+=1,this}writeUint32(e,t){return this._realloc(4),this._dataView.setUint32(this.position,e,void 0===t?this.endianness:t),this.position+=4,this}writeUint16(e,t){return this._realloc(2),this._dataView.setUint16(this.position,e,void 0===t?this.endianness:t),this.position+=2,this}writeUint8(e){return this._realloc(1),this._dataView.setUint8(this.position,e),this.position+=1,this}writeFloat32(e,t){return this._realloc(4),this._dataView.setFloat32(this.position,e,void 0===t?this.endianness:t),this.position+=4,this}writeFloat64(e,t){return this._realloc(8),this._dataView.setFloat64(this.position,e,void 0===t?this.endianness:t),this.position+=8,this}static memcpy(e,t,i,r,s){const a=new Uint8Array(e,t,s);s=new Uint8Array(i,r,s);a.set(s)}static arrayToNative(e,t){return t===this.endianness?e:this.flipArrayEndianness(e)}static nativeToEndian(e,t){return this.endianness===t?e:this.flipArrayEndianness(e)}static flipArrayEndianness(r){const s=new Uint8Array(r.buffer,r.byteOffset,r.byteLength);for(let i=0;i<r.byteLength;i+=r.BYTES_PER_ELEMENT)for(let e=i+r.BYTES_PER_ELEMENT-1,t=i;e>t;e--,t++){var a=s[t];s[t]=s[e],s[e]=a}return r}static createStringFromArray(t){const i=[];for(let e=0;e<t.length;e+=32768)i.push(String.fromCharCode.apply(void 0,t.subarray(e,e+32768)));return i.join("")}readUCS2String(e,t){return DataStream.createStringFromArray(this.readUint16Array(e,t))}writeUCS2String(e,t,i){void 0===i&&(i=e.length);let r=0;for(;r<e.length&&r<i;r++)this.writeUint16(e.charCodeAt(r),t);for(;r<i;r++)this.writeUint16(0);return this}readString(e,t){return void 0===t||"ASCII"===t?DataStream.createStringFromArray(this.mapUint8Array(void 0===e?this.byteLength-this.position:e)):new TextDecoder(t).decode(this.mapUint8Array(e))}writeString(t,e,i){if(void 0===e||"ASCII"===e)if(void 0!==i){let e;var r=Math.min(t.length,i);for(e=0;e<r;e++)this.writeUint8(t.charCodeAt(e));for(;e<i;e++)this.writeUint8(0)}else for(let e=0;e<t.length;e++)this.writeUint8(t.charCodeAt(e));else this.writeUint8Array((new TextEncoder).encode(t.substring(0,i)));return this}writeUtf8WithLen(e){e=(new TextEncoder).encode(e);return this.writeUint16(e.length).writeUint8Array(e)}readUtf8WithLen(){var e=this.readUint16();return(new TextDecoder).decode(this.mapUint8Array(e))}readCString(e){var t=this.byteLength-this.position,i=new Uint8Array(this._buffer,this._byteOffset+this.position);let r=t;void 0!==e&&(r=Math.min(e,t));let s=0;for(;s<r&&0!==i[s];s++);var a=DataStream.createStringFromArray(this.mapUint8Array(s));return void 0!==e?this.position+=r-s:s!==t&&(this.position+=1),a}writeCString(t,i){if(void 0!==i){let e;var r=Math.min(t.length,i);for(e=0;e<r;e++)this.writeUint8(t.charCodeAt(e));for(;e<i;e++)this.writeUint8(0)}else{for(let e=0;e<t.length;e++)this.writeUint8(t.charCodeAt(e));this.writeUint8(0)}return this}toUint8Array(){return new Uint8Array(this.buffer,this.byteOffset,this.byteLength)}}DataStream.BIG_ENDIAN=!1,DataStream.LITTLE_ENDIAN=!0,DataStream.endianness=0<new Int8Array(new Int16Array([1]).buffer)[0];class IOError extends Error{constructor(){super(...arguments),this.name="IOError"}}class VirtualFile{static async fromRealFile(t){try{const e=new DataStream(await t.arrayBuffer());return e._trimAlloc=()=>{},new this(e,t.name)}catch(e){if(e instanceof DOMException)throw new IOError(`File "${t.name}" could not be read (${e.name})`,{cause:e});throw e}}static fromBytes(e,t){let i=new DataStream(e);return i._trimAlloc=()=>{},new this(i,t)}static factory(e,t,i=0,r=e.byteLength){r=new DataView(e.buffer,e.byteOffset+i,r);const s=new DataStream(r);return s._trimAlloc=()=>{},new this(s,t)}constructor(e,t){this.stream=e,this.filename=t}readAsString(e){return this.stream.seek(0),this.stream.readString(this.stream.byteLength,e)}getBytes(){return new Uint8Array(this.stream.buffer,this.stream.byteOffset,this.stream.byteLength)}getSize(){return this.stream.byteLength}asFile(e){return new File([this.getBytes()],this.filename,{type:e})}}class IniFile{constructor(e){this.sections=new Map,e instanceof VirtualFile?this.fromVirtualFile(e):"object"==typeof e?this.fromJson(e):"string"==typeof e&&this.fromString(e)}fromVirtualFile(e){return this.fromString(e.readAsString())}fromString(e){return this.fromJson((new IniParser).parse(e))}fromJson(e){for(var t in e){var i;e.hasOwnProperty(t)&&(i=new IniSection(t).fromJson(e[t]),this.sections.set(t,i))}return this}toString(){let e=[];for(var t of this.sections.values())e.push(t.toString());return e.join("\r\n")}clone(){let i=new IniFile;return this.sections.forEach((e,t)=>{i.sections.set(t,e.clone())}),i}getOrCreateSection(e){let t=this.sections.get(e);return t||(t=new IniSection(e),this.sections.set(e,t)),t}getSection(e){return this.sections.get(e)}getOrderedSections(){return[...this.sections.values()]}mergeWith(e){return e.sections.forEach((e,t)=>{let i=this.getOrCreateSection(t);i.mergeWith(e)}),this}}class Format3{static decode(r,s,t){let a=new Uint8Array(s*t),n=0,o=0;for(let e=0;e<t;e++){let t=(r[n+1]<<8|r[n])-2;n+=2;let i=0;for(;0<t--;){let e=r[n++];if(0!==e)i++,a[o++]=e;else for(t--,e=r[n++],i+e>s&&(e=s-i&255),i+=e;0!=e--;)a[o++]=0}}return a}}class ShpImage{constructor(e){this.height=1,this.width=1,this.x=0,this.y=0,this.imageData=e??new Uint8Array(0)}clip(i,e){let t=new ShpImage;t.width=Math.min(this.width,i),t.height=Math.min(this.height,e);let r=new Uint8Array(i*e),s=0;for(let t=0;t<this.height&&!(t>=e);t++)for(let e=0;e<this.width;e++)e>=i||(r[s++]=this.imageData[t*this.width+e]);return t.imageData=r,t.x=this.x,t.y=this.y,t}}class ShpFile{constructor(e){this.height=0,this.width=0,this.numImages=0,this.images=[],e instanceof VirtualFile&&this.fromVirtualFile(e)}fromVirtualFile(e){this.filename=e.filename;let s=e.stream;if(0===s.readInt16()){this.width=s.readInt16(),this.height=s.readInt16(),this.numImages=s.readInt16();let r=[];for(let e=0;e<this.numImages;++e)r.push(this.readFrameHeader(s));this.images=[];for(let i=0;i<this.numImages;++i){var{compressionType:a,imageDataStartOffset:n,x:o,y:l,width:h,height:c}=r[i];let e=i<this.numImages-1?r[i+1].imageDataStartOffset:s.byteLength;e<n&&(e=s.byteLength);var d=e-n;s.seek(n);d=this.readImageData(s,h,c,a,d);let t=new ShpImage(d);t.x=o,t.y=l,t.width=h,t.height=c,this.images.push(t)}}}readFrameHeader(e){var t=e.readInt16(),i=e.readInt16(),r=e.readInt16(),s=e.readInt16(),a=e.readUint8();return e.readUint8(),e.readUint8(),e.readUint8(),e.readInt32(),e.readInt32(),{x:t,y:i,width:r,height:s,compressionType:a,imageDataStartOffset:e.readInt32()}}readImageData(r,e,s,t,i){var a=e*s;if(t<=1){var n=new Uint8Array(r.buffer,r.byteOffset+r.position,a);return r.position+=a,n}if(2===t){let t=0,i=new Uint8Array(a);for(let e=0;e<s;++e){var o=r.readUint16()-2;i.set(new Uint8Array(r.buffer,r.byteOffset+r.position,o),t),r.position+=o,t+=o}return i}if(3!==t)return new Uint8Array;t=new Uint8Array(r.buffer,r.byteOffset+r.position,i);return r.position+=i,Format3.decode(t,e,s)}getImage(e){if(e<0||this.images.length<=e)throw new RangeError(`Image index out of bounds (file=${this.filename}, index=${e}, length=${this.images.length})`);return this.images[e]}addImage(e){this.images.push(e),this.numImages++}clip(e,t){let i=new ShpFile;return i.filename=this.filename,i.width=Math.min(this.width,e),i.height=Math.min(this.height,t),i.images=this.images.map(e=>e.clip(i.width,i.height)),i.numImages=this.numImages,i}}var THREE=__webpack_require__(70),Vector3=THREE.Vector3;const normals1=[new Vector3(.54946297,-183e-6,-.835518),new Vector3(.00014400001,.54940403,-.83555698),new Vector3(-.54940403,-68000001e-12,-.83555698),new Vector3(106e-6,-.54946297,-.835518),new Vector3(.94900799,.00031599999,-.31525001),new Vector3(-186e-6,.94899702,-.31528401),new Vector3(-.94899702,.00031800001,-.31528401),new Vector3(-447e-6,-.94900799,-.31525001),new Vector3(.95084399,-279e-6,.30967101),new Vector3(202e-6,.95084798,.30965701),new Vector3(-.95084798,-70000002e-12,.30965701),new Vector3(147e-6,-.95084399,.30967101),new Vector3(.55237001,-11e-6,.83359897),new Vector3(19999999e-12,.55238003,.833592),new Vector3(-.55238003,57000001e-12,.83359301),new Vector3(-66000001e-12,-.55237001,.83359897)],normals2=[new Vector3(.67121398,.19849201,-.714194),new Vector3(.26964301,.58439398,-.76536),new Vector3(-.040546,.096988,-.99445897),new Vector3(-.57242799,-.091913998,-.81478697),new Vector3(-.17140099,-.57270998,-.80163902),new Vector3(.36255699,-.30299899,-.88133103),new Vector3(.81034702,-.34897199,-.470698),new Vector3(.103962,.93867201,-.328767),new Vector3(-.324047,.58766901,-.74137598),new Vector3(-.80086499,.34046099,-.49264699),new Vector3(-.66549802,-.59014702,-.45698899),new Vector3(.314767,-.803002,-.506073),new Vector3(.97262901,.151076,-.17655),new Vector3(.680291,.68423599,-.26272699),new Vector3(-.52007902,.82777703,-.210483),new Vector3(-.96164399,-.179001,-.207847),new Vector3(-.262714,-.937451,-.22840101),new Vector3(.219707,-.97130102,.091124997),new Vector3(.92380798,-.229975,.30608699),new Vector3(-.082488999,.97065997,.225866),new Vector3(-.59179801,.69678998,.40528899),new Vector3(-.92529601,.36660099,.097111002),new Vector3(-.705051,-.68777502,.172828),new Vector3(.7324,-.68036699,-.026304999),new Vector3(.85516202,.37458199,.358311),new Vector3(.47300601,.83648002,.276705),new Vector3(-.097617,.65411198,.750072),new Vector3(-.90412402,-.153725,.39865801),new Vector3(-.211916,-.85808998,.46773201),new Vector3(.50022697,-.67440802,.543091),new Vector3(.584539,-.110249,.80384099),new Vector3(.43737301,.45464399,.77588898),new Vector3(-.042440999,.083318003,.995619),new Vector3(-.59625101,.22013199,.77202803),new Vector3(-.506455,-.39697701,.76544899),new Vector3(.070569001,-.47847399,.87526202)],normals3=[new Vector3(.45651099,-.073968001,-.88663799),new Vector3(.50769401,.38511699,-.77067),new Vector3(.095431998,.22666401,-.96928602),new Vector3(-.35876599,.54318798,-.75910097),new Vector3(-.361276,.13299499,-.92292601),new Vector3(-.48311701,-.32406601,-.813375),new Vector3(-.018073,-.197559,-.980124),new Vector3(.3211,-.501477,-.80337799),new Vector3(.79949099,.069615997,-.59662998),new Vector3(.390971,.77130598,-.50222403),new Vector3(.080782004,.61448997,-.784778),new Vector3(-.73275,.41143101,-.54203498),new Vector3(-.73525399,.0091019999,-.67773098),new Vector3(-.80249399,-.39490801,-.44727099),new Vector3(-.13413,-.58915502,-.79680902),new Vector3(.71955299,-.37622699,-.58369303),new Vector3(.96687502,.173593,-.187132),new Vector3(.760831,.51910597,-.38944301),new Vector3(-.114642,.87551898,-.46938601),new Vector3(-.53236699,.76885903,-.354177),new Vector3(-.96226698,.024977,-.27095801),new Vector3(-.46738699,-.721986,-.51018202),new Vector3(.058449998,-.85235399,-.51968902),new Vector3(.49823299,-.74374002,-.44566301),new Vector3(.93915099,-.27024499,-.212044),new Vector3(.58393198,.80944198,-.061857),new Vector3(.183797,.97322798,-.138007),new Vector3(-.88435501,.45221901,-.115822),new Vector3(-.943178,-.33206701,.012138),new Vector3(-.69844002,-.70656699,-.113772),new Vector3(-.228411,-.95470601,-.190694),new Vector3(.73156399,-.675861,-.089588001),new Vector3(.96925098,.046804,.24158201),new Vector3(.85564703,.50347698,.119916),new Vector3(-.25115299,.96794701,-80999998e-12),new Vector3(-.64779502,.75674897,.087711997),new Vector3(-.96916401,.14519399,.1991),new Vector3(-.41479301,-.88896698,.194126),new Vector3(.25077501,-.961178,-.115109),new Vector3(.47862899,-.84259301,.246883),new Vector3(.89004397,-.39614201,.225595),new Vector3(.52405101,.76235998,.37970701),new Vector3(.11962,.94548202,.30291),new Vector3(-.76085001,.49007499,.42536199),new Vector3(-.86978501,-.20215,.450122),new Vector3(-.70946699,-.60242403,.36570701),new Vector3(.019308999,-.95887101,.28318599),new Vector3(.626113,-.564677,.53770101),new Vector3(.769943,-.126663,.62541503),new Vector3(.76419097,.35070199,.54131401),new Vector3(-.001878,.74136698,.67109799),new Vector3(-.37088001,.81836802,.43900099),new Vector3(-.71390897,.12865201,.68831801),new Vector3(-.295165,-.73866397,.60601401),new Vector3(.186195,-.73836899,.648184),new Vector3(.387523,-.35878301,.84917599),new Vector3(.481022,.124846,.86777401),new Vector3(.391808,.54505599,.741216),new Vector3(-.0035359999,.36559799,.93076599),new Vector3(-.42049801,.484961,.76680797),new Vector3(-.35490301,.019470001,.93470001),new Vector3(-.54783702,-.35920799,.75554299),new Vector3(-.106662,-.445115,.88909799),new Vector3(.086796001,-.059307002,.99445897)],normals4=[new Vector3(.52657801,-.35962099,-.77031702),new Vector3(.150482,.43598399,.88728398),new Vector3(.414195,.73825502,-.53237402),new Vector3(.075152002,.91624898,-.393498),new Vector3(-.316149,.93073601,-.18379299),new Vector3(-.77381903,.62333399,-.11251),new Vector3(-.90084201,.42853701,-.069568001),new Vector3(-.99894202,-.010971,.044665001),new Vector3(-.979761,-.15767001,-.123324),new Vector3(-.91127402,-.362371,-.19562),new Vector3(-.62406898,-.72094101,-.301301),new Vector3(-.310173,-.80934501,-.498752),new Vector3(.146613,-.81581903,-.55941403),new Vector3(-.71651602,-.69435602,-.066887997),new Vector3(.50397199,-.114202,-.85613698),new Vector3(.45549101,.87262702,-.176211),new Vector3(-.00501,-.114373,-.99342501),new Vector3(-.104675,-.327701,-.93896502),new Vector3(.56041199,.75258899,-.34575599),new Vector3(-.060575999,.82162797,-.566796),new Vector3(-.30234101,.79700702,-.522847),new Vector3(-.671543,.67074001,-.314863),new Vector3(-.77840102,-.12835699,.61450499),new Vector3(-.92404997,.278382,-.261985),new Vector3(-.69977301,-.55049098,-.45527801),new Vector3(-.56824797,-.51718903,-.64000797),new Vector3(.054097999,-.93286401,-.356143),new Vector3(.75838202,.57289302,-.31088799),new Vector3(.0036200001,.30502599,-.95233703),new Vector3(-.060849998,-.98688602,-.14951099),new Vector3(.63523,.045478001,-.77098298),new Vector3(.52170497,.241309,-.81828701),new Vector3(.26940399,.63542497,-.72364098),new Vector3(.045676,.67275399,-.738455),new Vector3(-.180511,.67465699,-.71571898),new Vector3(-.397131,.63664001,-.66104198),new Vector3(-.55200398,.47251499,-.687038),new Vector3(-.77217001,.08309,-.62996),new Vector3(-.669819,-.119533,-.73284),new Vector3(-.54045498,-.31844401,-.77878201),new Vector3(-.38613501,-.522789,-.75999397),new Vector3(-.261466,-.68856698,-.676395),new Vector3(-.019412,-.69610298,-.71767998),new Vector3(.30356899,-.48184401,-.82199299),new Vector3(.68193901,-.19512901,-.70490003),new Vector3(-.24488901,-.116562,-.96251899),new Vector3(.80075902,-.022979001,-.59854603),new Vector3(-.37027499,.095583998,-.92399102),new Vector3(-.33067101,-.32657799,-.88543999),new Vector3(-.16322,-.52757901,-.83367902),new Vector3(.12639,-.313146,-.941257),new Vector3(.34954801,-.27222601,-.89649802),new Vector3(.23991799,-.085825004,-.96699202),new Vector3(.390845,.081537001,-.91683799),new Vector3(.25526699,.26869699,-.92878503),new Vector3(.146245,.48043799,-.86474901),new Vector3(-.32601601,.47845599,-.81534898),new Vector3(-.46968201,-.112519,-.87563598),new Vector3(.81844002,-.25852001,-.51315099),new Vector3(-.474318,.292238,-.83043301),new Vector3(.778943,.39584199,-.48637101),new Vector3(.62409401,.39377299,-.67487001),new Vector3(.74088597,.203834,-.63995302),new Vector3(.48021701,.565768,-.67029703),new Vector3(.38093001,.42453501,-.82137799),new Vector3(-.093422003,.50112402,-.86031801),new Vector3(-.236485,.29619801,-.92538702),new Vector3(-.131531,.093959004,-.98684901),new Vector3(-.82356203,.29577699,-.48400599),new Vector3(.61106598,-.624304,-.486664),new Vector3(.069495998,-.52033001,-.85113299),new Vector3(.226522,-.66487902,-.711775),new Vector3(.47130799,-.56890398,-.67395699),new Vector3(.38842499,-.74262398,-.54556),new Vector3(.78367501,-.48072901,-.39338499),new Vector3(.962394,.135676,-.235349),new Vector3(.876607,.172034,-.449406),new Vector3(.63340503,.58979303,-.50094098),new Vector3(.182276,.80065799,-.57072097),new Vector3(.177003,.76413399,.62029701),new Vector3(-.544016,.675515,-.49772099),new Vector3(-.67929697,.28646699,-.67564201),new Vector3(-.59039098,.091369003,-.801929),new Vector3(-.82436001,-.13312399,-.55018902),new Vector3(-.71579403,-.33454201,-.61296099),new Vector3(.17428599,-.89248401,.416049),new Vector3(-.082528003,-.83712298,-.54075301),new Vector3(.28333101,-.88087398,-.37918901),new Vector3(.675134,-.42662701,-.60181701),new Vector3(.84372002,-.512335,-.160156),new Vector3(.97730398,-.098555997,-.18752),new Vector3(.846295,.522672,-.102947),new Vector3(.67714101,.72132498,-.145501),new Vector3(.32096499,.87089199,-.37219399),new Vector3(-.178978,.911533,-.37023601),new Vector3(-.44716901,.82670099,-.341474),new Vector3(-.70320302,.496328,-.50908101),new Vector3(-.97718102,.063562997,-.202674),new Vector3(-.87817001,-.412938,.241455),new Vector3(-.83583099,-.35855001,-.415728),new Vector3(-.499174,-.69343299,-.51959199),new Vector3(-.188789,-.92375302,-.33322501),new Vector3(.19225401,-.96936101,-.152896),new Vector3(.51594001,-.783907,-.34539199),new Vector3(.90592498,-.30095199,-.29787099),new Vector3(.99111199,-.127746,.037106998),new Vector3(.99513501,.098424003,-.0043830001),new Vector3(.76012301,.64627701,.067367002),new Vector3(.205221,.95958,-.192591),new Vector3(-.042750001,.97951299,-.19679099),new Vector3(-.43801701,.89892697,.0084920004),new Vector3(-.82199401,.48078501,-.30523899),new Vector3(-.89991701,.081710003,-.42833701),new Vector3(-.92661202,-.144618,-.347096),new Vector3(-.79365999,-.55779201,-.24283899),new Vector3(-.43134999,-.84777898,-.30855799),new Vector3(-.0054919999,-.96499997,.26219299),new Vector3(.58790499,-.80402601,-.088940002),new Vector3(.69949299,-.66768599,-.254765),new Vector3(.88930303,.359795,-.282291),new Vector3(.780972,.197037,.59267199),new Vector3(.52012098,.50669599,.68755698),new Vector3(.40389499,.69396102,.59605998),new Vector3(-.154983,.89923602,.40909001),new Vector3(-.65733802,.53716803,.528543),new Vector3(-.74619502,.33409101,.575827),new Vector3(-.62495202,-.049144,.77911502),new Vector3(.31814101,-.254715,.913185),new Vector3(-.555897,.405294,.725752),new Vector3(-.79443401,.099405997,.59916002),new Vector3(-.64036101,-.68946302,.33849499),new Vector3(-.12671299,-.73409498,.66711998),new Vector3(.105457,-.78081697,.61579502),new Vector3(.40799299,-.48091599,.77605498),new Vector3(.69513601,-.54512,.468647),new Vector3(.97319102,-.0064889998,.229908),new Vector3(.94689399,.317509,-.050799001),new Vector3(.56358302,.82561201,.027183),new Vector3(.325773,.94542301,.0069490001),new Vector3(-.171821,.98509699,-.0078149997),new Vector3(-.67044097,.73993897,.054768998),new Vector3(-.822981,.55496198,.121322),new Vector3(-.96619302,.117857,.229307),new Vector3(-.95376903,-.29470399,.058945),new Vector3(-.86438698,-.50272799,-.010015),new Vector3(-.53060901,-.84200603,-.097365998),new Vector3(-.162618,-.98407501,.071772002),new Vector3(.081446998,-.99601102,.036439002),new Vector3(.74598402,-.66596299,.00076199998),new Vector3(.94205701,-.32926899,-.064106002),new Vector3(.93970197,-.28108999,.194803),new Vector3(.77121401,.55067003,.319363),new Vector3(.641348,.73069,.23402099),new Vector3(.080682002,.99669099,.0098789996),new Vector3(-.046725001,.97664303,.20972501),new Vector3(-.53107601,.82100099,.209562),new Vector3(-.69581503,.65599,.29243499),new Vector3(-.97612202,.216709,-.014913),new Vector3(-.96166098,-.14412899,.23331399),new Vector3(-.772084,-.61364698,.165299),new Vector3(-.44960001,-.83605999,.314426),new Vector3(-.39269999,-.91461599,.096247002),new Vector3(.390589,-.91947001,.044890001),new Vector3(.58252901,-.79919797,.148127),new Vector3(.866431,-.48981199,.096864),new Vector3(.90458697,.111498,.41145),new Vector3(.95353699,.23232999,.191806),new Vector3(.497311,.77080297,.398177),new Vector3(.194066,.95631999,.218611),new Vector3(.422876,.882276,.206797),new Vector3(-.373797,.84956598,.37217399),new Vector3(-.53449702,.71402299,.4522),new Vector3(-.881827,.23716,.40759799),new Vector3(-.904948,-.014069,.42528901),new Vector3(-.751827,-.51281703,.41445801),new Vector3(-.50101501,-.69791698,.51175803),new Vector3(-.23519,-.92592299,.295555),new Vector3(.228983,-.95393997,.193819),new Vector3(.734025,-.63489801,.241062),new Vector3(.91375297,-.063253,-.40131599),new Vector3(.90573502,-.161487,.391875),new Vector3(.85892999,.342446,.38074899),new Vector3(.62448603,.60758102,.49077699),new Vector3(.28926399,.85747898,.42550799),new Vector3(.069968,.90216899,.42567101),new Vector3(-.28617999,.94069999,.182165),new Vector3(-.57401299,.80511898,-.14930899),new Vector3(.111258,.099717997,-.98877603),new Vector3(-.30539301,-.94422799,-.12316),new Vector3(-.60116601,-.78957599,.123163),new Vector3(-.290645,-.81213999,.50591898),new Vector3(-.064920001,-.87716299,.47578499),new Vector3(.408301,-.862216,.29978901),new Vector3(.56609702,-.72556603,.39126399),new Vector3(.83936399,-.427387,.33586901),new Vector3(.81889999,-.041305002,.57244802),new Vector3(.71978402,.41499701,.55649698),new Vector3(.88174403,.45027,.140659),new Vector3(.40182301,-.89822,-.17815199),new Vector3(-.054019999,.79134399,.60898),new Vector3(-.29377401,.76399398,.57446498),new Vector3(-.450798,.61034697,.65135098),new Vector3(-.63822103,.186694,.74687302),new Vector3(-.87287003,-.25712699,.41470799),new Vector3(-.58725703,-.52170998,.618828),new Vector3(-.35365799,-.64197397,.680291),new Vector3(.041648999,-.61127299,.79032302),new Vector3(.348342,-.77918297,.52108699),new Vector3(.499167,-.62244099,.602826),new Vector3(.79001898,-.30383101,.53250003),new Vector3(.66011798,.060733002,.74870199),new Vector3(.60492098,.29416099,.73996001),new Vector3(.38569701,.37934601,.84103203),new Vector3(.239693,.207876,.94833201),new Vector3(.012623,.25853199,.96591997),new Vector3(-.100557,.457147,.88368797),new Vector3(.046967,.62858802,.77631903),new Vector3(-.43039101,-.44540501,.785097),new Vector3(-.43429101,-.196228,.87913901),new Vector3(-.25663701,-.336867,.90590203),new Vector3(-.131372,-.15891001,.97851402),new Vector3(.102379,-.208767,.972592),new Vector3(.195687,-.450129,.87125802),new Vector3(.62731898,-.42314801,.65377098),new Vector3(.68743902,-.171583,.70568198),new Vector3(.27592,-.021255,.96094602),new Vector3(.45936701,.15746599,.87417799),new Vector3(.285395,.583184,.76055598),new Vector3(-.81217402,.46030301,.35846099),new Vector3(-.189068,.64122301,.743698),new Vector3(-.338875,.47648001,.811252),new Vector3(-.92099398,.347186,.176727),new Vector3(.040638998,.024465,.99887401),new Vector3(-.73913199,-.35374701,.57318997),new Vector3(-.60351199,-.28661501,.74405998),new Vector3(-.188676,-.547059,.81555402),new Vector3(-.026045,-.39782,.91709399),new Vector3(.26789701,-.649041,.71202302),new Vector3(.518246,-.28489101,.80638599),new Vector3(.493451,-.066532999,.86722499),new Vector3(-.328188,.140251,.93414301),new Vector3(.328188,.140251,.93414301),new Vector3(-.328188,.140251,.93414301),new Vector3(-.328188,.140251,.93414301),new Vector3(-.328188,.140251,.93414301)];class VoxelField{constructor(e,t,i){this.sizeX=e,this.sizeY=t,this.sizeZ=i,this.arr=new Array(e*t*i)}add(e){this.arr[e.x+e.y*this.sizeX+e.z*this.sizeX*this.sizeY]=e}get(e,t,i){if(!(e>=this.sizeX||t>=this.sizeY||i>=this.sizeZ))return this.arr[e+t*this.sizeX+i*this.sizeX*this.sizeY]}}var Section_THREE=__webpack_require__(70);class Section{get spanX(){return this.maxBounds.x-this.minBounds.x}get spanY(){return this.maxBounds.y-this.minBounds.y}get spanZ(){return this.maxBounds.z-this.minBounds.z}get scaleX(){return this.spanX/this.sizeX}get scaleY(){return this.spanY/this.sizeY}get scaleZ(){return this.spanZ/this.sizeZ}get scale(){return new Section_THREE.Vector3(this.scaleX,this.scaleY,this.scaleZ)}getAllVoxels(){let i=[],r=new VoxelField(this.sizeX+1,this.sizeY+1,this.sizeZ+1);for(let e=0,t=this.spans.length;e<t;e++){var s=this.spans[e].voxels;for(let e=0,t=s.length;e<t;e++){var a=s[e];i.push(a),r.add(a)}}return{voxels:i,voxelField:r}}getNormals(){switch(this.normalsMode){case 1:return normals1;case 2:return normals2;case 3:return normals3;case 4:return normals4;default:throw new Error("Invalid normalsmode "+this.normalsMode)}}scaleHvaMatrix(e){return(e=e.clone()).elements[12]*=this.hvaMultiplier,e.elements[13]*=this.hvaMultiplier,e.elements[14]*=this.hvaMultiplier,e}toPlain(){return{name:this.name,normalsMode:this.normalsMode,minBounds:this.minBounds.toArray(),maxBounds:this.maxBounds.toArray(),sizeX:this.sizeX,sizeY:this.sizeY,sizeZ:this.sizeZ,hvaMultiplier:this.hvaMultiplier,transfMatrix:this.transfMatrix.toArray(),spans:this.spans}}fromPlain(e){return this.name=e.name,this.normalsMode=e.normalsMode,this.minBounds=(new Section_THREE.Vector3).fromArray(e.minBounds),this.maxBounds=(new Section_THREE.Vector3).fromArray(e.maxBounds),this.sizeX=e.sizeX,this.sizeY=e.sizeY,this.sizeZ=e.sizeZ,this.hvaMultiplier=e.hvaMultiplier,this.transfMatrix=(new Section_THREE.Matrix4).fromArray(e.transfMatrix),this.spans=e.spans,this}}class VxlHeader{read(e){this.fileName=e.readCString(16),this.paletteCount=e.readUint32(),this.headerCount=e.readUint32(),this.tailerCount=e.readUint32(),this.bodySize=e.readUint32(),this.paletteRemapStart=e.readUint8(),this.paletteRemapEnd=e.readUint8(),e.seek(e.position+768)}}VxlHeader.size=32;var VxlFile_THREE=__webpack_require__(70);class VxlFile{constructor(e){this.voxelCount=0,e instanceof VirtualFile&&this.fromVirtualFile(e)}fromVirtualFile(e){this.filename=e.filename;let s=e.stream;if(this.sections=[],!(s.byteLength<VxlHeader.size)){let r=new VxlHeader;if(r.read(s),r.headerCount&&r.tailerCount&&r.tailerCount===r.headerCount){for(let e=0;e<r.headerCount;++e){const n=new Section;this.readSectionHeader(n,s),this.sections.find(e=>e.name===n.name)&&console.warn(`Duplicate section name "${n.name}" found in VXL "${this.filename}".`),this.sections.push(n)}var a=s.position;s.seek(s.position+r.bodySize);let t=[];for(let e=0;e<r.tailerCount;++e)t[e]=this.readSectionTailer(this.sections[e],s);let i=0;for(let e=0;e<r.headerCount;++e)s.seek(a),i+=this.readSectionBodySpans(this.sections[e],t[e],s);this.voxelCount=i}}}readSectionHeader(e,t){e.name=t.readCString(16),t.readUint32(),t.readUint32(),t.readUint32()}readSectionTailer(e,t){var i=t.readUint32(),r=t.readUint32(),s=t.readUint32();return e.hvaMultiplier=t.readFloat32(),e.transfMatrix=this.readTransfMatrix(t),e.minBounds=new VxlFile_THREE.Vector3(t.readFloat32(),t.readFloat32(),t.readFloat32()),e.maxBounds=new VxlFile_THREE.Vector3(t.readFloat32(),t.readFloat32(),t.readFloat32()),e.sizeX=t.readUint8(),e.sizeY=t.readUint8(),e.sizeZ=t.readUint8(),e.normalsMode=t.readUint8(),{startingSpanOffset:i,endingSpanOffset:r,dataSpanOffset:s}}readTransfMatrix(t){let i=[];for(let e=0;e<3;++e)i.push(t.readFloat32(),t.readFloat32(),t.readFloat32(),t.readFloat32());return i.push(0,0,0,1),(new VxlFile_THREE.Matrix4).fromArray(i).transpose()}readSectionBodySpans(e,t,i){i.seek(i.position+t.startingSpanOffset);var{sizeX:r,sizeY:s,sizeZ:a}=e;let n=new Array(s);for(let t=0;t<s;++t){n[t]=new Array(r);for(let e=0;e<r;++e)n[t][e]=i.readInt32()}let o=new Array(s);for(let t=0;t<s;++t){o[t]=new Array(r);for(let e=0;e<r;++e)o[t][e]=i.readInt32()}let l=e.spans=[],h=0;for(let t=0;t<s;++t)for(let e=0;e<r;++e){var c={x:e,y:t,voxels:this.readSpanVoxels(n[t][e],o[t][e],e,t,a,i)};l.push(c),h+=c.voxels.length}return h}readSpanVoxels(e,t,i,r,s,a){if(-1===e||-1===t)return[];let n=[];for(let t=0;t<s;){t+=a.readUint8();var o=a.readUint8();for(let e=0;e<o;++e){var l={x:i,y:r,z:t++,colorIndex:a.readUint8(),normalIndex:a.readUint8()};n.push(l)}a.readUint8()}return n}fromPlain(e){return this.sections=e.sections.map(e=>(new Section).fromPlain(e)),this.voxelCount=e.voxelCount,this}toPlain(){return{sections:this.sections.map(e=>e.toPlain()),voxelCount:this.voxelCount}}getSection(e){return this.sections[e]}}var DataPrecencyFlags,TmpImage_THREE=__webpack_require__(70);!function(e){e[e.ExtraData=1]="ExtraData",e[e.ZData=2]="ZData",e[e.DamagedData=4]="DamagedData"}(DataPrecencyFlags=DataPrecencyFlags||{});const unsignInt8=e=>e<0?e+256:e;class TmpImage{constructor(e,t,i){this.fromStream(e,t,i)}fromStream(e,t,i){this.x=e.readInt32(),this.y=e.readInt32(),e.readInt32(),e.readInt32();var r=e.readInt32();this.extraX=e.readInt32(),this.extraY=e.readInt32(),this.extraWidth=e.readInt32(),this.extraHeight=e.readInt32();var s=e.readUint32();this.height=e.readUint8(),this.terrainType=e.readUint8(),this.rampType=e.readUint8(),this.radarLeft=this.readRadarRgb(e.readInt8(),e.readInt8(),e.readInt8()),this.radarRight=this.readRadarRgb(e.readInt8(),e.readInt8(),e.readInt8()),e.seek(e.position+3),this.tileData=new Uint8Array(e.buffer,e.byteOffset+e.position,t*i/2),e.position+=t*i/2,this.hasZData=(s&DataPrecencyFlags.ZData)===DataPrecencyFlags.ZData,this.hasZData&&(e.position+=t*i/2),this.hasExtraData=(s&DataPrecencyFlags.ExtraData)===DataPrecencyFlags.ExtraData,this.hasExtraData&&(s=Math.abs(this.extraWidth*this.extraHeight),this.extraData=new Uint8Array(e.buffer,e.byteOffset+e.position,s),e.position+=s),this.hasZData&&this.hasExtraData&&0<r&&r<e.byteLength&&(e.position+=Math.abs(this.extraWidth*this.extraHeight))}readRadarRgb(e,t,i){return new TmpImage_THREE.Color(unsignInt8(e)/255,unsignInt8(t)/255,unsignInt8(i)/255)}}class TmpFile{constructor(e){this.images=[],e instanceof VirtualFile&&this.fromVirtualFile(e)}fromVirtualFile(e){let t=e.stream;this.width=t.readInt32(),this.height=t.readInt32(),this.blockWidth=t.readInt32(),this.blockHeight=t.readInt32();var i=this.width*this.height,r=new Uint8Array(t.buffer,t.byteOffset+t.position,4*i);this.images=[];for(let e=0;e<i;e++){var s=r[4*e+3]<<24|r[4*e+2]<<16|r[4*e+1]<<8|r[4*e];t.seek(s);s=new TmpImage(t,this.blockWidth,this.blockHeight);this.images.push(s)}}}class Base64{static encode(e){return void 0!==globalThis.btoa?globalThis.btoa(e):Buffer.from(e,"binary").toString("base64")}static decode(e){return void 0!==globalThis.atob?globalThis.atob(e):Buffer.from(e,"base64").toString("binary")}static isBase64(e){return!!e.match(/^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$/)}}function pad(e,t="0000"){e=""+e;return t.substring(0,t.length-e.length)+e}function equalsIgnoreCase(e,t){return e.toLowerCase()===t.toLowerCase()}function binaryStringToUint8Array(t){var i=t.length;let r=new Uint8Array(i);for(let e=0;e<i;e++)r[e]=t.charCodeAt(e);return r}function base64StringToUint8Array(e){return binaryStringToUint8Array(Base64.decode(e))}function uint8ArrayToBase64String(e){return Base64.encode(uint8ArrayToBinaryString(e))}function uint8ArrayToBinaryString(e){return e.reduce((e,t)=>e+String.fromCharCode(t),"")}function utf16ToBinaryString(t){var i=t.length;let r="";for(let e=0;e<i;e++){var s=t.charCodeAt(e);r+=String.fromCharCode(s>>8),r+=String.fromCharCode(255&s)}return r}function binaryStringToUtf16(t){var i=t.length;let r="";for(let e=0;e<i;e+=2){var s=(t.charCodeAt(e)<<8)+t.charCodeAt(e+1);r+=String.fromCharCode(s)}return r}function bufferToHexString(e){const t=[],i=new DataView(e);for(let e=0;e<i.byteLength;e+=4){const s=i.getUint32(e);var r="00000000",r=(r+s.toString(16)).slice(-r.length);t.push(r)}return t.join("")}class Color{static fromRgb(e,t,i){return new Color(e,t,i)}static fromHsv(e,t,i){let r=0,s=0,a=0;if(e=e/255*360%360,i/=255,0===(t/=255))r=i,s=i,a=i;else{var n=e/60,e=Math.floor(n),n=n-e,o=i*(1-t),l=i*(1-t*n),h=i*(1-t*(1-n));switch(e){case 0:r=i,s=h,a=o;break;case 1:r=l,s=i,a=o;break;case 2:r=o,s=i,a=h;break;case 3:r=o,s=l,a=i;break;case 4:r=h,s=o,a=i;break;case 5:r=i,s=o,a=l}}return Color.fromRgb(Math.floor(255*r),Math.floor(255*s),Math.floor(255*a))}constructor(e,t,i){this.r=e,this.g=t,this.b=i}asHex(){return(this.r<<16)+(this.g<<8)+this.b}asHexString(){return"#"+pad(this.asHex().toString(16),"000000")}clone(){return new Color(this.r,this.g,this.b)}}function getRandomInt(e,t){return Math.floor(Math.random()*(t+1-e))+e}function clamp(e,t,i){return Math.min(i,Math.max(e,t))}function isBetween(e,t,i){return t<=e&&e<=i}function lerp(e,t,i){return(1-i)*e+i*t}function truncToDecimals(e,t){if(!e)return e;t=10**t;return 0<=e?Math.floor(e*t)/t:Math.ceil(e*t)/t}function roundToDecimals(e,t){if(!e)return e;t=10**t;return Math.round(e*t)/t}function floorTo(e,t){return Math.floor(e/t)*t}function fnv32a(i){let r=2166136261;for(let e=0,t=i.length;e<t;++e)r^=i[e],r+=(r<<1)+(r<<4)+(r<<7)+(r<<8)+(r<<24);return r>>>0}class Palette{constructor(e){e instanceof VirtualFile?this.fromVirtualFile(e):"object"==typeof e&&this.fromJson(e)}fromVirtualFile(e){e=e.stream.readUint8Array(768);this.fromJson(e)}fromJson(t){this.colors=[];for(let e=0;e<t.length/3;++e)this.colors.push(Color.fromRgb(4*t[3*e],4*t[3*e+1],4*t[3*e+2]));this._hash=this.computeHash(this.colors)}getColor(e){return this.colors[e]}getColorAsHex(e){return this.getColor(e).asHex()}setColors(e){this.colors=e,this._hash=this.computeHash(this.colors)}get size(){return this.colors.length}get hash(){return this._hash}computeHash(e){let t=new Uint8Array(3*this.size),i=0;for(var r of e)t[i]=r.r,t[i+1]=r.g,t[i+2]=r.b,i+=3;return fnv32a(t)}clone(){let e=new Palette;return e.colors=this.colors.map(e=>e.clone()),e._hash=this._hash,e}remap(t){var i=[63,59,55,52,48,44,41,37,33,30,26,22,19,15,11,8];for(let e=Palette.REMAP_START_IDX;e<Palette.REMAP_START_IDX+i.length;e++)this.colors[e].r=Math.floor(t.r/255*i[e-Palette.REMAP_START_IDX]*4),this.colors[e].g=Math.floor(t.g/255*i[e-Palette.REMAP_START_IDX]*4),this.colors[e].b=Math.floor(t.b/255*i[e-Palette.REMAP_START_IDX]*4);return this._hash=this.computeHash(this.colors),this}}Palette.REMAP_START_IDX=16;class GameMath{static reverseSinTableLookup(e,t,i,r){for(;t<=i;){var s=Math.floor((t+i)/2),a=this.SIN_TABLE[s];if(a===e)return s;(r?e<a:a<e)?t=s+1:i=s-1}return Math.abs(e-this.SIN_TABLE[t])<Math.abs(e-this.SIN_TABLE[i])?t:i}static pow(e,t){if(!Number.isFinite(e)||!Number.isFinite(t)||Number.isSafeInteger(e)&&Number.isSafeInteger(t))return e**t;if(!Number.isSafeInteger(t))throw new Error("Exponent must be a safe integer");return Math.floor(e*this.EXP_10_PRECISION)**t/this.EXP_10_PRECISION**t}static sqrt(e){if(0===e)return 0;var t;let i=e/3;for(;t=i,i=(e/i+i)/2,5e-15<Math.abs(t-i););return i}static sin(e){if(!Number.isFinite(e))return NaN;if(!e)return e;e=e/(2*Math.PI)-Math.floor(e/(2*Math.PI)),e=Math.floor(e*this.SIN_TABLE.length);return this.SIN_TABLE[e]}static cos(e){return this.sin(e+Math.PI/2)}static asin(e){if(!isBetween(e,-1,1))return NaN;if(!e)return 0;let t;var i=this.SIN_TABLE.length;return t=0<e?2*Math.PI*this.reverseSinTableLookup(e,0,i/4,!1)/i:Math.PI-2*Math.PI*this.reverseSinTableLookup(e,i/2,.75*i,!0)/i,t}static acos(e){return Math.PI/2-this.asin(e)}static atan2(e,t){if(Number.isNaN(t)||Number.isNaN(e))return NaN;let i;return i=Number.isFinite(e)||Number.isFinite(t)?Number.isFinite(t)&&0!==e?Number.isFinite(e)&&0!==t?this.atan2FiniteNonZero(e,t):this.signIncZero(e)*Math.PI*.5:this.signIncZero(e)*(this.signIncZero(t)<0?Math.PI:0):Math.sign(e)*Math.PI*(0<Math.sign(t)?.25:.75),i}static atan2FiniteNonZero(e,t){var i=Math.abs(t),r=Math.abs(e),s=Math.min(i,r)/Math.max(i,r),a=s*s;let n=((-.0464964749*a+.15931422)*a-.327622764)*a*s+s;return i<r&&(n=Math.PI/2-n),t<0&&(n=Math.PI-n),e<0&&(n=-n),n}static signIncZero(e){return e===-1/0||1/e<0?-1:1}}GameMath.PRECISION=6,GameMath.EXP_10_PRECISION=10**GameMath.PRECISION,GameMath.SIN_TABLE=[0,.004848117819001859,.009696121685978396,.014543897651582654,.01939133177182437,.024238310110748135,.0290847187431114,.03393044375706223,.03877537125681671,.043619387365336,.04846237822700296,.05330423001029823,.05814482891047582,.06298406115223795,.06782181299240934,.0726579707226106,.07749242067193093,.08232504920959989,.08715574274765817,.09198438774362744,.09681087070317909,.10163507818280187,.10645689679246824,.11127621319829964,.11609291412523022,.12090688635966935,.12571801675216268,.13052619222005157,.13533129975013108,.14013322640130627,.14493185930724672,.1497270856790396,.15451879280784048,.15930686806752256,.16409119891732396,.1688716729044928,.17364817766693033,.17842060093583212,.18318883053832663,.18795275440011186,.19271226054808968,.19746723711299752,.20221757233203794,.20696315455150538,.2117038722294107,.21643961393810288,.22117026836688775,.2258957243246448,.23061587074244014,.2353305966761376,.24003979130900588,.2447433439543238,.24944114405798126,.25413308120107847,.25881904510252074,.26349892562161076,.2681726127606373,.272839996667461,.27750096763809573,.28215541611928774,.2868032327110902,.29144430816943495,.2960785334086999,.3007057995042731,.3053259976951131,.30993901938630514,.31454475615161365,.31914309973603083,.323733942058321,.328317175213561,.33289269147567657,.3374603832999741,.3420201433256687,.34657186437840753,.3511154394727888,.3556507618148765,.3601777248047104,.36469622203881186,.3692061473126844,.3737073946233105,.3781998581716425,.3826834323650898,.3871580118200006,.3916234913641391,.3960797660391568,.4005267311030606,.4049642820326736,.4093923145260926,.4138107245051391,.4182194081178064,.42261826174069944,.4270071819814715,.4313860656812534,.4357548099170794,.4401133120043048,.44446146949902104,.4487991802004621,.4531263421534082,.4574428536505808,.4617486132350339,.46604351970253877,.4703274721039625,.4746003697476404,.4788621122017435,.4831125992966384,.48735173112724234,.49157940805537054,.49579553071207916,.49999999999999994,.5041927170956704,.5083735834518556,.5125425007998652,.5166993711518628,.5208440968031697,.5249765803345602,.5290967246145525,.5332044328016912,.5372996083468239,.5413821549953696,.5454519767895825,.549508978070806,.5535530634817223,.5575841379685927,.5616021067834929,.5656068754865385,.5695983499481065,.573576436351046,.5775410411928851,.5814920712880266,.5854294337699405,.5893530360933448,.593262786036382,.5971585917027862,.6010403615240428,.6049080042615417,.6087614290087207,.6126005451932028,.6164252625789254,.62023549126826,.6240311417041269,.6278121246720986,.6315783513024975,.6353297330724851,.6390661818081416,.6427876096865393,.6464939292378065,.6501850533471834,.6538608952570697,.6575213685690636,.6611663872459932,.6647958656139378,.6684097183642425,.6720078605555224,.6755902076156601,.6791566753437932,.6827071799122926,.6862416378687335,.6897599661378576,.6932620820235242,.696747903210655,.7002173477671685,.7036703341459059,.7071067811865475,.710526608117521,.713929734557899,.7173160805192894,.7206855664077146,.7240381130254825,.7273736415730487,.7306920736508674,.7339933312612352,.7372773368101241,.7405440131090046,.7437932833766612,.747025071240996,.7502393007408245,.7534358963276606,.7566147828674927,.7597758856425494,.7629191303530553,.766044443118978,.7691517504817651,.7722409794060692,.7753120572814658,.7783649119241599,.7813994715786823,.7844156649195757,.7874134210530723,.7903926695187593,.7933533402912352,.7962953637817558,.7992186708398696,.8021231927550437,.8050088612582783,.8078756085237111,.8107233671702122,.8135520702629676,.8163616513150519,.8191520442889918,.821923183598318,.8246750041091067,.8274074411415104,.8301204304712788,.8328139083312671,.8354878114129364,.8381420768678404,.8407766423091032,.8433914458128856,.845986425919841,.848561521636559,.8511166724369997,.8536518182639162,.8561668995302665,.8586618571206132,.8611366323925137,.8635911671778986,.8660254037844386,.8684392849969005,.870832754078492,.8732057547721958,.8755582313020908,.8778901283746645,.8802013911801111,.8824919653936212,.8847617971766577,.8870108331782216,.8892390205361062,.8914463068781385,.8936326403234122,.8957979694835052,.8979422434636881,.9000654118641211,.9021674247810376,.9042482328079179,.9063077870366499,.9083460390586793,.9103629409661466,.9123584453530141,.9143325053161794,.9162850744565779,.918216106880274,.9201255571995389,.9220133805339185,.9238795325112867,.9257239692688903,.9275466474543786,.9293475242268224,.9311265572577219,.9328837047320004,.9346189253489884,.9363321783233931,.9380234233862578,.9396926207859083,.9413397312888874,.942964716180876,.9445675372676047,.9461481568757504,.947706537853822,.9492426435730339,.9507564379281666,.9522478853384153,.9537169507482269,.955163599628123,.9565877979755122,.9579895123154889,.9593687097016201,.9607253577167205,.9620594244736131,.9633708786158803,.9646596893185995,.9659258262890683,.9671692597675166,.9683899605278059,.969587899878116,.97076304966162,.9719153822571454,.9730448705798238,.9741514880817275,.9752352087524931,.9762960071199334,.9773338582506355,.9783487377505475,.9793406217655515,.980309486982024,.9812553106273847,.9821780704706308,.98307774482286,.9839543125377807,.984807753012208,.9856380461865492,.9864451725452739,.987229113117374,.987989849476809,.9887273637429388,.9894416385809445,.9901326572022359,.9908004033648453,.9914448613738104,.9920660160815423,.9926638528881819,.993238357741943,.9937895171394426,.9943173181260184,.9948217482960331,.9953027957931658,.9957604493106914,.9961946980917455,.9966055319295779,.996992941167792,.9973569167005722,.9976974499728977,.9980145329807433,.9983081582712682,.9985783189429907,.9988250086459504,.9990482215818578,.99924795250423,.9994241967185149,.9995769500822006,.9997062090049132,.9998119704485015,.9998942319271075,.9999529915072262,.9999882478077495,1,.9999882478077495,.9999529915072262,.9998942319271075,.9998119704485015,.9997062090049132,.9995769500822006,.9994241967185149,.99924795250423,.9990482215818578,.9988250086459504,.9985783189429907,.9983081582712682,.9980145329807433,.9976974499728977,.9973569167005722,.996992941167792,.9966055319295779,.9961946980917455,.9957604493106914,.9953027957931658,.9948217482960331,.9943173181260184,.9937895171394426,.993238357741943,.9926638528881819,.9920660160815423,.9914448613738105,.9908004033648453,.9901326572022359,.9894416385809446,.9887273637429388,.987989849476809,.987229113117374,.9864451725452739,.9856380461865492,.984807753012208,.9839543125377807,.98307774482286,.9821780704706307,.9812553106273847,.9803094869820241,.9793406217655516,.9783487377505476,.9773338582506356,.9762960071199334,.9752352087524931,.9741514880817276,.9730448705798238,.9719153822571455,.9707630496616201,.969587899878116,.9683899605278059,.9671692597675166,.9659258262890683,.9646596893185995,.9633708786158803,.9620594244736133,.9607253577167205,.9593687097016202,.9579895123154889,.9565877979755123,.9551635996281231,.9537169507482269,.9522478853384153,.9507564379281666,.949242643573034,.9477065378538221,.9461481568757505,.9445675372676048,.942964716180876,.9413397312888873,.9396926207859084,.9380234233862579,.9363321783233931,.9346189253489885,.9328837047320006,.9311265572577219,.9293475242268225,.9275466474543786,.9257239692688904,.9238795325112867,.9220133805339185,.920125557199539,.918216106880274,.916285074456578,.9143325053161794,.9123584453530141,.9103629409661467,.9083460390586793,.90630778703665,.904248232807918,.9021674247810377,.9000654118641213,.8979422434636883,.8957979694835051,.8936326403234123,.8914463068781386,.8892390205361062,.8870108331782218,.8847617971766579,.8824919653936212,.8802013911801111,.8778901283746644,.8755582313020909,.8732057547721958,.8708327540784921,.8684392849969006,.8660254037844387,.8635911671778987,.8611366323925138,.858661857120613,.8561668995302665,.8536518182639163,.8511166724369997,.8485615216365591,.8459864259198412,.8433914458128856,.8407766423091031,.8381420768678404,.8354878114129364,.8328139083312672,.8301204304712789,.8274074411415107,.8246750041091069,.8219231835983182,.819152044288992,.8163616513150518,.8135520702629675,.8107233671702123,.8078756085237112,.8050088612582784,.802123192755044,.7992186708398695,.7962953637817556,.7933533402912352,.7903926695187593,.7874134210530723,.7844156649195758,.7813994715786824,.7783649119241601,.775312057281466,.7722409794060693,.769151750481765,.766044443118978,.7629191303530551,.7597758856425494,.756614782867493,.7534358963276608,.7502393007408243,.7470250712409959,.7437932833766611,.7405440131090045,.7372773368101241,.7339933312612353,.7306920736508675,.7273736415730488,.7240381130254827,.7206855664077148,.7173160805192896,.713929734557899,.710526608117521,.7071067811865476,.703670334145906,.7002173477671687,.6967479032106549,.6932620820235241,.6897599661378576,.6862416378687336,.6827071799122926,.6791566753437933,.6755902076156604,.6720078605555225,.6684097183642426,.6647958656139381,.6611663872459935,.6575213685690636,.6538608952570697,.6501850533471835,.6464939292378067,.6427876096865395,.6390661818081418,.635329733072485,.6315783513024975,.6278121246720986,.6240311417041269,.6202354912682602,.6164252625789255,.612600545193203,.6087614290087209,.6049080042615419,.6010403615240432,.5971585917027862,.593262786036382,.5893530360933449,.5854294337699406,.5814920712880268,.5775410411928852,.5735764363510459,.5695983499481064,.5656068754865385,.5616021067834929,.5575841379685929,.5535530634817224,.5495089780708062,.5454519767895827,.5413821549953699,.5372996083468241,.5332044328016912,.5290967246145525,.5249765803345602,.5208440968031698,.516699371151863,.5125425007998654,.5083735834518555,.5041927170956703,.49999999999999994,.49579553071207916,.49157940805537065,.48735173112724245,.48311259929663863,.4788621122017437,.47460036974764064,.47032747210396275,.46604351970253877,.4617486132350339,.45744285365058085,.4531263421534083,.44879918020046233,.4444614694990212,.4401133120043047,.43575480991707927,.43138606568125343,.4270071819814714,.4226182617406995,.4182194081178065,.4138107245051393,.40939231452609276,.4049642820326738,.40052673110306086,.3960797660391572,.39162349136413904,.38715801182000065,.3826834323650899,.37819985817164264,.3737073946233107,.3692061473126843,.36469622203881175,.3601777248047104,.3556507618148765,.35111543947278884,.34657186437840765,.3420201433256689,.3374603832999743,.33289269147567685,.32831717521356135,.3237339420583214,.31914309973603083,.3145447561516137,.30993901938630525,.30532599769511326,.30070579950427334,.29607853340870016,.2914443081694349,.2868032327110902,.28215541611928774,.2775009676380958,.2728399966674611,.26817261276063753,.263498925621611,.258819045102521,.2541330812010788,.24944114405798165,.24474334395432376,.24003979130900596,.2353305966761377,.23061587074244033,.225895724324645,.22117026836688802,.21643961393810274,.21170387222941067,.20696315455150538,.20221757233203796,.19746723711299763,.19271226054808982,.18795275440011205,.18318883053832688,.17842060093583242,.17364817766693072,.16887167290449276,.16409119891732402,.15930686806752267,.15451879280784062,.1497270856790398,.14493185930724697,.14013322640130613,.135331299750131,.13052619222005157,.12571801675216274,.12090688635966945,.11609291412523036,.11127621319829985,.1064568967924685,.10163507818280217,.09681087070317945,.09198438774362741,.0871557427476582,.08232504920959997,.07749242067193107,.07265797072261079,.0678218129924096,.06298406115223781,.05814482891047573,.0533042300102982,.04846237822700297,.04361938736533607,.038775371256816835,.03393044375706242,.029084718743111644,.02423831011074843,.01939133177182472,.014543897651583058,.009696121685978408,.004848117819001927,12246467991473532e-32,-.004848117819001238,-.009696121685978163,-.01454389765158237,-.019391331771824474,-.02423831011074774,-.029084718743111398,-.03393044375706173,-.03877537125681659,-.04361938736533583,-.048462378227003174,-.05330423001029795,-.05814482891047593,-.06298406115223758,-.06782181299240934,-.07265797072261056,-.07749242067193128,-.08232504920959974,-.08715574274765794,-.09198438774362716,-.09681087070317876,-.10163507818280193,-.10645689679246781,-.1112762131982996,-.11609291412523012,-.12090688635966965,-.1257180167521625,-.13052619222005177,-.13533129975013078,-.14013322640130632,-.14493185930724675,-.14972708567904,-.1545187928078404,-.15930686806752198,-.16409119891732377,-.16887167290449254,-.17364817766693047,-.17842060093583176,-.18318883053832663,-.1879527544001114,-.1927122605480896,-.19746723711299738,-.20221757233203816,-.20696315455150513,-.21170387222941087,-.21643961393810252,-.2211702683668878,-.22589572432464475,-.23061587074244053,-.23533059667613745,-.2400397913090053,-.2447433439543235,-.24944114405798098,-.2541330812010786,-.25881904510252035,-.2634989256216107,-.26817261276063686,-.2728399966674609,-.27750096763809556,-.2821554161192879,-.28680323271108993,-.29144430816943506,-.29607853340869994,-.30070579950427306,-.30532599769511304,-.3099390193863046,-.3145447561516135,-.3191430997360306,-.3237339420583211,-.3283171752135607,-.33289269147567657,-.3374603832999737,-.34202014332566866,-.3465718643784074,-.35111543947278906,-.35565076181487626,-.36017772480471055,-.3646962220388115,-.3692061473126845,-.3737073946233105,-.3781998581716428,-.38268343236508967,-.38715801182000004,-.3916234913641388,-.39607976603915657,-.40052673110306064,-.4049642820326732,-.40939231452609254,-.41381072450513867,-.4182194081178062,-.4226182617406993,-.4270071819814716,-.4313860656812532,-.43575480991707943,-.4401133120043045,-.444461469499021,-.4487991802004621,-.4531263421534085,-.4574428536505806,-.46174861323503374,-.46604351970253854,-.47032747210396214,-.4746003697476404,-.47886211220174313,-.4831125992966384,-.4873517311272422,-.4915794080553708,-.49579553071207894,-.5000000000000001,-.50419271709567,-.5083735834518556,-.5125425007998652,-.5166993711518633,-.5208440968031696,-.5249765803345596,-.5290967246145523,-.533204432801691,-.5372996083468239,-.5413821549953693,-.5454519767895825,-.5495089780708056,-.5535530634817222,-.5575841379685926,-.5616021067834931,-.5656068754865384,-.5695983499481065,-.5735764363510458,-.577541041192885,-.5814920712880266,-.5854294337699408,-.5893530360933448,-.5932627860363815,-.597158591702786,-.6010403615240426,-.6049080042615417,-.6087614290087203,-.6126005451932028,-.6164252625789249,-.6202354912682599,-.6240311417041268,-.6278121246720987,-.6315783513024973,-.6353297330724852,-.6390661818081416,-.6427876096865393,-.6464939292378065,-.6501850533471829,-.6538608952570695,-.6575213685690635,-.6611663872459933,-.6647958656139376,-.6684097183642425,-.6720078605555221,-.6755902076156601,-.6791566753437931,-.6827071799122927,-.6862416378687334,-.6897599661378577,-.693262082023524,-.696747903210655,-.7002173477671685,-.7036703341459061,-.7071067811865475,-.7105266081175206,-.7139297345578989,-.7173160805192892,-.7206855664077146,-.7240381130254823,-.7273736415730487,-.7306920736508671,-.7339933312612352,-.737277336810124,-.7405440131090048,-.743793283376661,-.747025071240996,-.7502393007408242,-.7534358963276607,-.7566147828674927,-.7597758856425493,-.7629191303530554,-.7660444431189779,-.7691517504817651,-.7722409794060688,-.7753120572814659,-.7783649119241597,-.7813994715786822,-.7844156649195754,-.7874134210530722,-.7903926695187589,-.7933533402912349,-.7962953637817558,-.79921867083987,-.8021231927550437,-.8050088612582785,-.8078756085237111,-.8107233671702119,-.8135520702629674,-.8163616513150515,-.8191520442889916,-.8219231835983181,-.8246750041091064,-.8274074411415104,-.830120430471279,-.8328139083312671,-.8354878114129365,-.8381420768678401,-.8407766423091032,-.8433914458128855,-.8459864259198411,-.8485615216365587,-.8511166724369996,-.8536518182639165,-.8561668995302664,-.8586618571206132,-.8611366323925135,-.8635911671778986,-.8660254037844385,-.8684392849969005,-.8708327540784918,-.8732057547721956,-.8755582313020905,-.8778901283746643,-.8802013911801112,-.8824919653936215,-.8847617971766578,-.8870108331782218,-.889239020536106,-.8914463068781383,-.8936326403234122,-.8957979694835049,-.897942243463688,-.9000654118641208,-.9021674247810375,-.9042482328079179,-.90630778703665,-.9083460390586792,-.9103629409661468,-.912358445353014,-.9143325053161795,-.9162850744565778,-.918216106880274,-.9201255571995388,-.9220133805339183,-.9238795325112865,-.9257239692688903,-.9275466474543786,-.9293475242268223,-.9311265572577219,-.9328837047320003,-.9346189253489884,-.9363321783233929,-.9380234233862578,-.9396926207859082,-.9413397312888873,-.9429647161808761,-.9445675372676049,-.9461481568757504,-.9477065378538222,-.9492426435730339,-.9507564379281666,-.9522478853384153,-.9537169507482267,-.9551635996281229,-.956587797975512,-.9579895123154888,-.9593687097016201,-.9607253577167205,-.9620594244736131,-.9633708786158804,-.9646596893185994,-.9659258262890683,-.9671692597675166,-.9683899605278059,-.9695878998781159,-.97076304966162,-.9719153822571452,-.9730448705798238,-.9741514880817276,-.975235208752493,-.9762960071199334,-.9773338582506355,-.9783487377505475,-.9793406217655514,-.980309486982024,-.9812553106273846,-.9821780704706307,-.98307774482286,-.9839543125377805,-.984807753012208,-.9856380461865493,-.9864451725452739,-.9872291131173742,-.9879898494768089,-.9887273637429387,-.9894416385809445,-.9901326572022358,-.9908004033648452,-.9914448613738104,-.9920660160815423,-.9926638528881818,-.993238357741943,-.9937895171394426,-.9943173181260184,-.994821748296033,-.9953027957931658,-.9957604493106913,-.9961946980917455,-.9966055319295779,-.996992941167792,-.9973569167005722,-.9976974499728977,-.9980145329807433,-.9983081582712682,-.9985783189429907,-.9988250086459504,-.9990482215818578,-.99924795250423,-.9994241967185149,-.9995769500822006,-.9997062090049132,-.9998119704485015,-.9998942319271076,-.9999529915072262,-.9999882478077495,-1,-.9999882478077495,-.9999529915072262,-.9998942319271076,-.9998119704485015,-.9997062090049132,-.9995769500822006,-.9994241967185149,-.99924795250423,-.9990482215818578,-.9988250086459504,-.9985783189429907,-.9983081582712682,-.9980145329807433,-.9976974499728977,-.9973569167005724,-.996992941167792,-.9966055319295779,-.9961946980917455,-.9957604493106914,-.9953027957931658,-.9948217482960331,-.9943173181260185,-.9937895171394426,-.993238357741943,-.9926638528881819,-.9920660160815424,-.9914448613738105,-.9908004033648453,-.9901326572022358,-.9894416385809446,-.9887273637429387,-.987989849476809,-.9872291131173742,-.986445172545274,-.9856380461865493,-.9848077530122081,-.9839543125377807,-.9830777448228601,-.9821780704706308,-.9812553106273846,-.9803094869820241,-.9793406217655515,-.9783487377505476,-.9773338582506355,-.9762960071199335,-.9752352087524931,-.9741514880817276,-.9730448705798239,-.9719153822571454,-.9707630496616201,-.969587899878116,-.968389960527806,-.9671692597675167,-.9659258262890684,-.9646596893185995,-.9633708786158806,-.9620594244736133,-.9607253577167206,-.9593687097016202,-.9579895123154889,-.9565877979755121,-.955163599628123,-.9537169507482268,-.9522478853384154,-.9507564379281668,-.949242643573034,-.9477065378538223,-.9461481568757506,-.944567537267605,-.9429647161808762,-.9413397312888874,-.9396926207859083,-.9380234233862579,-.936332178323393,-.9346189253489885,-.9328837047320004,-.9311265572577221,-.9293475242268224,-.9275466474543788,-.9257239692688904,-.9238795325112866,-.9220133805339186,-.9201255571995389,-.9182161068802742,-.9162850744565779,-.9143325053161796,-.9123584453530141,-.9103629409661469,-.9083460390586794,-.9063077870366503,-.9042482328079181,-.9021674247810376,-.9000654118641209,-.8979422434636882,-.895797969483505,-.8936326403234123,-.8914463068781384,-.8892390205361063,-.887010833178222,-.8847617971766579,-.8824919653936216,-.8802013911801113,-.8778901283746645,-.8755582313020907,-.8732057547721959,-.870832754078492,-.8684392849969007,-.8660254037844386,-.8635911671778989,-.8611366323925137,-.8586618571206134,-.8561668995302666,-.8536518182639167,-.8511166724369998,-.848561521636559,-.8459864259198413,-.8433914458128857,-.8407766423091034,-.8381420768678404,-.8354878114129367,-.8328139083312672,-.8301204304712791,-.8274074411415107,-.8246750041091067,-.8219231835983183,-.8191520442889918,-.8163616513150517,-.8135520702629676,-.8107233671702121,-.8078756085237113,-.8050088612582788,-.802123192755044,-.7992186708398701,-.796295363781756,-.7933533402912352,-.7903926695187591,-.7874134210530724,-.7844156649195756,-.7813994715786825,-.7783649119241599,-.7753120572814661,-.7722409794060691,-.7691517504817653,-.7660444431189781,-.7629191303530556,-.7597758856425495,-.7566147828674927,-.753435896327661,-.7502393007408246,-.7470250712409963,-.7437932833766612,-.740544013109005,-.7372773368101242,-.7339933312612357,-.7306920736508676,-.7273736415730492,-.7240381130254828,-.7206855664077145,-.7173160805192891,-.7139297345578991,-.7105266081175208,-.7071067811865477,-.7036703341459063,-.7002173477671687,-.6967479032106556,-.6932620820235246,-.6897599661378577,-.6862416378687334,-.6827071799122926,-.679156675343793,-.6755902076156605,-.6720078605555223,-.6684097183642427,-.6647958656139378,-.6611663872459935,-.6575213685690637,-.6538608952570701,-.6501850533471836,-.6464939292378064,-.6427876096865396,-.6390661818081416,-.6353297330724854,-.6315783513024976,-.627812124672099,-.624031141704127,-.6202354912682606,-.6164252625789255,-.6126005451932034,-.6087614290087209,-.6049080042615417,-.6010403615240425,-.5971585917027863,-.5932627860363818,-.589353036093345,-.585429433769941,-.5814920712880269,-.5775410411928856,-.5735764363510465,-.5695983499481065,-.5656068754865391,-.561602106783493,-.5575841379685926,-.5535530634817225,-.5495089780708059,-.5454519767895828,-.5413821549953696,-.5372996083468242,-.5332044328016913,-.5290967246145529,-.5249765803345603,-.5208440968031696,-.5166993711518632,-.5125425007998651,-.5083735834518559,-.5041927170956704,-.5000000000000004,-.49579553071207927,-.49157940805537115,-.48735173112724256,-.48311259929663913,-.4788621122017438,-.47460036974764036,-.4703274721039621,-.4660435197025389,-.46174861323503363,-.45744285365058096,-.4531263421534088,-.44879918020046244,-.4444614694990217,-.4401133120043052,-.43575480991708015,-.4313860656812539,-.42700718198147153,-.4226182617406992,-.4182194081178066,-.413810724505139,-.40939231452609287,-.40496428203267354,-.400526731103061,-.3960797660391569,-.39162349136413954,-.38715801182000076,-.3826834323650904,-.37819985817164276,-.3737073946233104,-.3692061473126848,-.36469622203881186,-.3601777248047109,-.3556507618148766,-.3511154394727894,-.34657186437840776,-.34202014332566943,-.3374603832999744,-.3328926914756765,-.32831717521356063,-.32373394205832107,-.31914309973603056,-.3145447561516138,-.3099390193863049,-.30532599769511337,-.30070579950427384,-.2960785334087003,-.29144430816943584,-.2868032327110907,-.28215541611928785,-.2775009676380955,-.2728399966674612,-.2681726127606372,-.2634989256216111,-.2588190451025207,-.2541330812010789,-.24944114405798135,-.24474334395432432,-.24003979130900607,-.23533059667613823,-.23061587074244044,-.2258957243246447,-.22117026836688813,-.21643961393810288,-.21170387222941123,-.2069631545515055,-.20221757233203852,-.19746723711299774,-.19271226054809037,-.1879527544001122,-.18318883053832655,-.17842060093583256,-.1736481776669304,-.16887167290449245,-.16409119891732413,-.15930686806752234,-.15451879280784075,-.14972708567904036,-.1449318593072471,-.14013322640130713,-.13533129975013158,-.13052619222005168,-.1257180167521624,-.12090688635966958,-.11609291412523004,-.11127621319829996,-.10645689679246818,-.10163507818280229,-.09681087070317913,-.09198438774362797,-.08715574274765832,-.08232504920960054,-.0774924206719312,-.07265797072261047,-.06782181299240972,-.06298406115223794,-.0581448289104763,-.05330423001029832,-.04846237822700354,-.043619387365336194,-.038775371256817404,-.03393044375706254,-.02908471874311221,-.02423831011074855,-.019391331771824397,-.014543897651582293,-.009696121685978531,-.004848117819001606];var Vector2_THREE=__webpack_require__(70);class Vector2 extends Vector2_THREE.Vector2{length(){return GameMath.sqrt(this.x*this.x+this.y*this.y)}angle(){let e=GameMath.atan2(this.y,this.x);return e<0&&(e+=2*Math.PI),e}distanceTo(e){return GameMath.sqrt(this.distanceToSquared(e))}rotateAround(e,t){var i=GameMath.cos(t),r=GameMath.sin(t),s=this.x-e.x,t=this.y-e.y;return this.x=s*i-t*r+e.x,this.y=s*r+t*i+e.y,this}}var Quaternion_THREE=__webpack_require__(70);class Quaternion extends Quaternion_THREE.Quaternion{setFromEuler(e,t){if(!e||!e.isEuler)throw new Error("THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.");var i=e.x,r=e.y,s=e.z,a=e.order,n=GameMath.cos(i/2),o=GameMath.cos(r/2),e=GameMath.cos(s/2),i=GameMath.sin(i/2),r=GameMath.sin(r/2),s=GameMath.sin(s/2);return"XYZ"===a?(this._x=i*o*e+n*r*s,this._y=n*r*e-i*o*s,this._z=n*o*s+i*r*e,this._w=n*o*e-i*r*s):"YXZ"===a?(this._x=i*o*e+n*r*s,this._y=n*r*e-i*o*s,this._z=n*o*s-i*r*e,this._w=n*o*e+i*r*s):"ZXY"===a?(this._x=i*o*e-n*r*s,this._y=n*r*e+i*o*s,this._z=n*o*s+i*r*e,this._w=n*o*e-i*r*s):"ZYX"===a?(this._x=i*o*e-n*r*s,this._y=n*r*e+i*o*s,this._z=n*o*s-i*r*e,this._w=n*o*e+i*r*s):"YZX"===a?(this._x=i*o*e+n*r*s,this._y=n*r*e+i*o*s,this._z=n*o*s-i*r*e,this._w=n*o*e-i*r*s):"XZY"===a&&(this._x=i*o*e-n*r*s,this._y=n*r*e-i*o*s,this._z=n*o*s+i*r*e,this._w=n*o*e+i*r*s),!1!==t&&this.onChangeCallback(),this}setFromAxisAngle(e,t){var i=t/2,t=GameMath.sin(i);return this._x=e.x*t,this._y=e.y*t,this._z=e.z*t,this._w=GameMath.cos(i),this.onChangeCallback(),this}setFromRotationMatrix(e){let t=e.elements,i=t[0],r=t[4],s=t[8],a=t[1],n=t[5],o=t[9],l=t[2],h=t[6],c=t[10],d=i+n+c,u;return 0<d?(u=.5/GameMath.sqrt(d+1),this._w=.25/u,this._x=(h-o)*u,this._y=(s-l)*u,this._z=(a-r)*u):n<i&&c<i?(u=2*GameMath.sqrt(1+i-n-c),this._w=(h-o)/u,this._x=.25*u,this._y=(r+a)/u,this._z=(s+l)/u):c<n?(u=2*GameMath.sqrt(1+n-i-c),this._w=(s-l)/u,this._x=(r+a)/u,this._y=.25*u,this._z=(o+h)/u):(u=2*GameMath.sqrt(1+c-i-n),this._w=(a-r)/u,this._x=(s+l)/u,this._y=(o+h)/u,this._z=.25*u),this.onChangeCallback(),this}length(){return GameMath.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)}slerp(e,t){if(0===t)return this;if(1===t)return this.copy(e);var i=this._x,r=this._y,s=this._z,a=this._w;let n=a*e._w+i*e._x+r*e._y+s*e._z;if(n<0?(this._w=-e._w,this._x=-e._x,this._y=-e._y,this._z=-e._z,n=-n):this.copy(e),1<=n)return this._w=a,this._x=i,this._y=r,this._z=s,this;var o=1-n*n;if(o<=Number.EPSILON){var l=1-t;return this._w=l*a+t*this._w,this._x=l*i+t*this._x,this._y=l*r+t*this._y,this._z=l*s+t*this._z,this.normalize()}e=GameMath.sqrt(o),l=GameMath.atan2(e,n),o=GameMath.sin((1-t)*l)/e,e=GameMath.sin(t*l)/e;return this._w=a*o+this._w*e,this._x=i*o+this._x*e,this._y=r*o+this._y*e,this._z=s*o+this._z*e,this.onChangeCallback(),this}}var HighBridgeHeadType,PaletteType,TheaterType,MixFileFlags,EngineType,GameResSource,GameModeType,Vector3_THREE=__webpack_require__(70);class Vector3_Vector3 extends Vector3_THREE.Vector3{applyEuler(e){return e&&e.isEuler||console.error("THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order."),this.applyQuaternion(_quaternion.setFromEuler(e))}applyAxisAngle(e,t){return this.applyQuaternion(_quaternion.setFromAxisAngle(e,t))}length(){return GameMath.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)}projectOnPlane(e){return _vector.copy(this).projectOnVector(e),this.sub(_vector)}reflect(e){return this.sub(_vector.copy(e).multiplyScalar(2*this.dot(e)))}angleTo(e){e=this.dot(e)/GameMath.sqrt(this.lengthSq()*e.lengthSq());return GameMath.acos(clamp(e,-1,1))}distanceTo(e){return GameMath.sqrt(this.distanceToSquared(e))}setFromSpherical(e){var t=GameMath.sin(e.phi)*e.radius;return this.x=t*GameMath.sin(e.theta),this.y=GameMath.cos(e.phi)*e.radius,this.z=t*GameMath.cos(e.theta),this}setFromCylindrical(e){return this.x=e.radius*GameMath.sin(e.theta),this.y=e.y,this.z=e.radius*GameMath.cos(e.theta),this}}const _quaternion=new Quaternion,_vector=new Vector3_Vector3;class Coords{static tileToWorld(e,t){return{x:e*Coords.LEPTONS_PER_TILE,y:t*Coords.LEPTONS_PER_TILE}}static vecWorldToGround(e){return new Vector2(e.x,e.z)}static vecGroundToWorld(e){return new Vector3_Vector3(e.x,0,e.y)}static tileHeightToWorld(e){return e*(Coords.LEPTONS_PER_TILE/2)*Coords.zScale}static worldToTileHeight(e){return e/(Coords.LEPTONS_PER_TILE/2*Coords.zScale)}static tile3dToWorld(e,t,i){t=Coords.tileToWorld(e,t),i=Coords.tileHeightToWorld(i);return new Vector3_Vector3(t.x,i,t.y)}static screenDistanceToWorld(e,t){return{x:Math.floor((e+2*t)/2*Coords.ISO_WORLD_SCALE),y:Math.floor((2*t-e)/2*Coords.ISO_WORLD_SCALE)}}static getWorldTileSize(){return Coords.LEPTONS_PER_TILE}}Coords.ISO_TILE_SIZE=30,Coords.LEPTONS_PER_TILE=256,Coords.ISO_WORLD_SCALE=Coords.LEPTONS_PER_TILE/Coords.ISO_TILE_SIZE,Coords.ISO_CAMERA_ALPHA=Math.PI/6,Coords.ISO_CAMERA_BETA=Math.PI/4,Coords.COS_ISO_CAMERA_BETA=GameMath.cos(Coords.ISO_CAMERA_BETA),Coords.zScale=Coords.COS_ISO_CAMERA_BETA/GameMath.cos(Coords.ISO_CAMERA_ALPHA);class TileSetEntry{constructor(e,t){this.owner=e,this.index=t,this.files=[]}addFile(e){this.files.push(e)}setAnimation(e){this.animation=e}getAnimation(){return this.animation}getTmpFile(e,t,i=!1){if(this.files.length){t=this.files[t(0,this.files.length-1)];return t.images[Math.min(e,t.images.length-1)].hasDamagedData?this.files[Math.min(i?1:0,this.files.length-1)]:t}}getRelativeTilePositions(){return this.files[0].images.map(({x:e,y:t,height:i},r)=>({subTile:r,rx:(e+2*t)/2/Coords.ISO_TILE_SIZE,ry:(2*t-e)/2/Coords.ISO_TILE_SIZE,z:i}))}}class TileSet{constructor(e,t,i){this.fileName=e,this.setName=t,this.tilesInSet=i,this.entries=[]}}class TileSetAnim{constructor(e,t,i,r){this.name=e,this.subTile=t,this.offsetX=i,this.offsetY=r}}!function(e){e[e.TopLeft=0]="TopLeft",e[e.BottomRight=1]="BottomRight",e[e.TopRight=2]="TopRight",e[e.BottomLeft=3]="BottomLeft",e[e.MiddleTlBr=4]="MiddleTlBr",e[e.MiddleTrBl=5]="MiddleTrBl"}(HighBridgeHeadType=HighBridgeHeadType||{});const highBridgeHeadNames=new Map([[HighBridgeHeadType.TopLeft,["BridgeTopLeft1","BridgeTopLeft2"]],[HighBridgeHeadType.BottomRight,["BridgeBottomRight1","BridgeBottomRight2"]],[HighBridgeHeadType.TopRight,["BridgeTopRight1","BridgeTopRight2"]],[HighBridgeHeadType.BottomLeft,["BridgeBottomLeft1","BridgeBottomLeft2"]],[HighBridgeHeadType.MiddleTlBr,["BridgeMiddle1"]],[HighBridgeHeadType.MiddleTrBl,["BridgeMiddle2"]]]);class TileSets{constructor(e){this.theaterIni=e,this.tileSets=[],this.orderedEntries=[],this.highBridgeSetNums=[this.getGeneralValue("BridgeSet"),this.getGeneralValue("WoodBridgeSet")],this.cliffSetNums=[this.getGeneralValue("CliffSet"),this.getGeneralValue("WaterCliffs"),this.getGeneralValue("DestroyableCliffs")]}getTile(e){return this.orderedEntries[e]}getTileImage(e,t,i){let r=this.getTile(e);if(!r)throw new Error(`TileNum ${e} not found`);i=r.getTmpFile(t,i);if(!i||t>=i.images.length)throw new Error(`SubTile ${t} not found`);return i.images[t]}getSetNum(e){var t=this.orderedEntries[e];if(!t)throw new Error("Invalid tileNum "+e);return this.tileSets.indexOf(t.owner)}getTileNumFromSet(i,r=0){let s=0;return this.tileSets.some((e,t)=>t===i?(s+=r,!0):(s+=e.entries.length,!1)),s}getGeneralValue(e){let t=this.theaterIni.getSection("General");if(!t)throw new Error("Missing [General] section in theather ini");return t.getNumber(e)}loadTileData(e,t){this.tileSets.length=0,this.orderedEntries.length=0,this.initTileSets(e,t),this.initAnimations()}readMaxTileNum(){let t=0,i=0;for(;;){var r="TileSet"+pad(t,"0000");let e=this.theaterIni.getSection(r);if(!e)break;t++,i+=e.getNumber("TilesInSet")}return i}initTileSets(a,n){let e=0,t;for(var i;;){if(i="TileSet"+pad(e,"0000"),t=this.theaterIni.getSection(i),!t)break;e++;let s=new TileSet(t.getString("FileName"),t.getString("SetName"),t.getNumber("TilesInSet"));this.tileSets.push(s);for(let r=1;r<=s.tilesInSet;r++){let i=new TileSetEntry(s,r-1);var o="a".charCodeAt(0);for(let t=o-1;t<="z".charCodeAt(0);t++)if(!(t>=o&&"Bridges"===s.setName)){let e=s.fileName+pad(r,"00");t>=o&&(e+=String.fromCharCode(t)),e+=n;var l=a.get(e);if(!l)break;i.addFile(l)}s.entries.push(i),this.orderedEntries.push(i)}}}initAnimations(){var r=this.theaterIni.getOrderedSections();for(let e=this.tileSets.length;e<r.length;++e){let t=r[e],i=this.tileSets.find(e=>e.setName===t.name);if(i)for(let e=1;e<=i.tilesInSet;++e){var s="Tile"+pad(e,"00"),a=s+"Anim",n=t.getString(a);n?(s=new TileSetAnim(n,t.getNumber(s+"AttachesTo"),t.getNumber(s+"XOffset"),t.getNumber(s+"YOffset")),i.entries[e-1].setAnimation(s)):console.warn(`Missing anim "${a}" for tileset `+i.setName)}}}isLAT(e){return e===this.getGeneralValue("RoughTile")||e===this.getGeneralValue("SandTile")||e===this.getGeneralValue("GreenTile")||e===this.getGeneralValue("PaveTile")}isCLAT(e){return e===this.getGeneralValue("ClearToRoughLat")||e===this.getGeneralValue("ClearToSandLat")||e===this.getGeneralValue("ClearToGreenLat")||e===this.getGeneralValue("ClearToPaveLat")}getLAT(e){return e===this.getGeneralValue("ClearToRoughLat")?this.getGeneralValue("RoughTile"):e===this.getGeneralValue("ClearToSandLat")?this.getGeneralValue("SandTile"):e===this.getGeneralValue("ClearToGreenLat")?this.getGeneralValue("GreenTile"):e===this.getGeneralValue("ClearToPaveLat")?this.getGeneralValue("PaveTile"):-1}getCLATSet(e){return e===this.getGeneralValue("RoughTile")?this.getGeneralValue("ClearToRoughLat"):e===this.getGeneralValue("SandTile")?this.getGeneralValue("ClearToSandLat"):e===this.getGeneralValue("GreenTile")?this.getGeneralValue("ClearToGreenLat"):e===this.getGeneralValue("PaveTile")?this.getGeneralValue("ClearToPaveLat"):-1}canConnectTiles(e,t){if(e===t)return!1;var i=this.getGeneralValue("GreenTile"),r=this.getGeneralValue("PaveTile"),s=this.getGeneralValue("MiscPaveTile"),a=this.getGeneralValue("ShorePieces"),n=this.getGeneralValue("WaterBridge"),o=this.getGeneralValue("PavedRoads"),l=this.getGeneralValue("Medians");return!(e===i&&t===a||t===i&&e===a)&&(!(e===i&&t===n||t===i&&e===n)&&(!(e===r&&t===o||t===r&&e===o)&&(!(e===r&&t===s||t===r&&e===s)&&!(e===r&&t===l||t===r&&e===l))))}getHighBridgeHeadType(e){for(var[t,i]of highBridgeHeadNames)for(var r of i)if(this.getGeneralValue(r)===e+1)return t}getOppositeHighBridgeHeadType(e){switch(e){case HighBridgeHeadType.TopLeft:return HighBridgeHeadType.BottomRight;case HighBridgeHeadType.TopRight:return HighBridgeHeadType.BottomLeft;case HighBridgeHeadType.BottomLeft:return HighBridgeHeadType.TopRight;case HighBridgeHeadType.BottomRight:return HighBridgeHeadType.TopLeft;case HighBridgeHeadType.MiddleTlBr:case HighBridgeHeadType.MiddleTrBl:throw new Error("Middle bridge heads can't have opposites");default:throw new Error("Unhandled headType "+e)}}isCliffTile(e){return this.cliffSetNums.includes(this.getSetNum(e))}isHighBridgeBoundaryTile(e){if(this.highBridgeSetNums.includes(this.getSetNum(e))){e=this.getTile(e),e=this.getHighBridgeHeadType(e.index);return void 0!==e&&![HighBridgeHeadType.MiddleTlBr,HighBridgeHeadType.MiddleTrBl].includes(e)}return!1}isHighBridgeMiddleTile(e){if(this.highBridgeSetNums.includes(this.getSetNum(e))){e=this.getTile(e),e=this.getHighBridgeHeadType(e.index);return void 0!==e&&[HighBridgeHeadType.MiddleTlBr,HighBridgeHeadType.MiddleTrBl].includes(e)}return!1}}!function(e){e[e.None=0]="None",e[e.Iso=1]="Iso",e[e.Unit=2]="Unit",e[e.Overlay=3]="Overlay",e[e.Anim=4]="Anim",e[e.Custom=5]="Custom",e[e.Default=6]="Default"}(PaletteType=PaletteType||{});class Theater{static factory(e,t,i,r,s){var a=s.get(i.isoPaletteName);if(!a)throw new Error(`Missing palette "${i.isoPaletteName}"`);var n=s.get(i.overlayPaletteName);if(!n)throw new Error(`Missing palette "${i.overlayPaletteName}"`);var o=s.get(i.unitPaletteName);if(!o)throw new Error(`Missing palette "${i.unitPaletteName}"`);var l=s.get("anim.pal");if(!l)throw new Error("Missing anim palette");var h=s.get(i.libPaletteName);if(!h)throw new Error("Missing lib palette "+i.libPaletteName);let c=new TileSets(t);return c.loadTileData(r,i.extension),new this(e,i,s,a,n,o,l,h,c)}constructor(e,t,i,r,s,a,n,o,l){this.type=e,this.settings=t,this.palettes=i,this.isoPalette=r,this.ovlPalette=s,this.unitPalette=a,this.animPalette=n,this.libPalette=o,this.tileSets=l}getPalette(e,t){switch(e){case PaletteType.Anim:return this.animPalette;case PaletteType.Overlay:return this.ovlPalette;case PaletteType.Unit:return this.unitPalette;case PaletteType.Custom:if("lib"===t)return this.libPalette;var i=this.palettes.get(t+".pal");if(!i)throw new Error(`Custom palette "${t}" not found`);return i;default:PaletteType.Iso;return this.isoPalette}}}!function(e){e[e.None=0]="None",e[e.Temperate=1]="Temperate",e[e.Urban=2]="Urban",e[e.Snow=4]="Snow",e[e.Lunar=8]="Lunar",e[e.Desert=16]="Desert",e[e.NewUrban=32]="NewUrban",e[e.All=63]="All"}(TheaterType=TheaterType||{});const version="0.81.0";class AudioBagFile{constructor(){this.fileData=new Map}fromVirtualFile(e,t){var i,r;for([i,r]of t.entries){var s=this.buildWavData(e.stream,r);this.fileData.set(i,s)}return this}getFileList(){return[...this.fileData.keys()]}containsFile(e){return this.fileData.has(e)}openFile(e){if(!this.containsFile(e))throw new Error(`File "${e}" not found`);return new VirtualFile(this.fileData.get(e),e)}buildWavData(e,t){let i=new DataStream;var r,s,a,n,o=0<(1&t.flags)?2:1;let l=0;0<(2&t.flags)?(i.writeString("RIFF"),i.writeUint32(t.length+36),i.writeString("WAVE"),i.writeString("fmt "),i.writeInt32(16),i.writeInt16(1),i.writeInt16(o),i.writeUint32(t.sampleRate),i.writeUint32(2*o*t.sampleRate),i.writeInt16(2*o),i.writeInt16(16),i.writeString("data"),i.writeUint32(t.length)):0<(8&t.flags)&&(r=11100*o*(t.sampleRate/22050|0),s=t.chunkSize,a=1017*(n=Math.max(2,Math.ceil(t.length/s))),n=n*s,l=n-t.length,i.writeString("RIFF"),i.writeUint32(52+n),i.writeString("WAVE"),i.writeString("fmt "),i.writeUint32(20),i.writeInt16(17),i.writeInt16(o),i.writeUint32(t.sampleRate),i.writeInt32(r),i.writeInt16(s),i.writeInt16(4),i.writeInt16(2),i.writeInt16(1017),i.writeString("fact"),i.writeUint32(4),i.writeInt32(a),i.writeString("data"),i.writeUint32(n)),e.seek(t.offset),i.writeUint8Array(e.readUint8Array(t.length));for(let e=0;e<l;e++)i.writeUint8(0);return i.seek(0),i._trimAlloc=()=>{},i}}class IdxEntry{}class IdxFile{constructor(e){this.entries=new Map,this.parse(e)}parse(t){var e=t.readCString(4);if("GABA"!==e)throw new Error(`Unable to load Idx file, did not find magic id, found ${e} instead`);e=t.readInt32();if(2!==e)throw new Error(`Unable to load Idx file, did not find magic number 2, found ${e} instead`);var i=t.readInt32();for(let e=0;e<i;e++){const s=new IdxEntry;let e=t.readString(16);var r=e.indexOf("\0");0!==r&&(e=e.substr(0,r)),s.filename=e+".wav",s.offset=t.readUint32(),s.length=t.readUint32(),s.sampleRate=t.readUint32(),s.flags=t.readUint32(),s.chunkSize=t.readUint32(),this.entries.set(s.filename,s)}}}function swapBytes(e){return e=((e=(e<<16>>>0|e>>>16)>>>0)<<8>>>0&4278255360|e>>>8&16711935)>>>0}class Blowfish{constructor(i){this.m_p=new Uint32Array([608135816,2242054355,320440878,57701188,2752067618,698298832,137296536,3964562569,1160258022,953160567,3193202383,887688300,3232508343,3380367581,1065670069,3041331479,2450970073,2306472731]),this.m_s=[new Uint32Array([3509652390,2564797868,805139163,3491422135,3101798381,1780907670,3128725573,4046225305,614570311,3012652279,134345442,2240740374,1667834072,1901547113,2757295779,4103290238,227898511,1921955416,1904987480,2182433518,2069144605,3260701109,2620446009,720527379,3318853667,677414384,3393288472,3101374703,2390351024,1614419982,1822297739,2954791486,3608508353,3174124327,2024746970,1432378464,3864339955,2857741204,1464375394,1676153920,1439316330,715854006,3033291828,289532110,2706671279,2087905683,3018724369,1668267050,732546397,1947742710,3462151702,2609353502,2950085171,1814351708,2050118529,680887927,999245976,1800124847,3300911131,1713906067,1641548236,4213287313,1216130144,1575780402,4018429277,3917837745,3693486850,3949271944,596196993,3549867205,258830323,2213823033,772490370,2760122372,1774776394,2652871518,566650946,4142492826,1728879713,2882767088,1783734482,3629395816,2517608232,2874225571,1861159788,326777828,3124490320,2130389656,2716951837,967770486,1724537150,2185432712,2364442137,1164943284,2105845187,998989502,3765401048,2244026483,1075463327,1455516326,1322494562,910128902,469688178,1117454909,936433444,3490320968,3675253459,1240580251,122909385,2157517691,634681816,4142456567,3825094682,3061402683,2540495037,79693498,3249098678,1084186820,1583128258,426386531,1761308591,1047286709,322548459,995290223,1845252383,2603652396,3431023940,2942221577,3202600964,3727903485,1712269319,422464435,3234572375,1170764815,3523960633,3117677531,1434042557,442511882,3600875718,1076654713,1738483198,4213154764,2393238008,3677496056,1014306527,4251020053,793779912,2902807211,842905082,4246964064,1395751752,1040244610,2656851899,3396308128,445077038,3742853595,3577915638,679411651,2892444358,2354009459,1767581616,3150600392,3791627101,3102740896,284835224,4246832056,1258075500,768725851,2589189241,3069724005,3532540348,1274779536,3789419226,2764799539,1660621633,3471099624,4011903706,913787905,3497959166,737222580,2514213453,2928710040,3937242737,1804850592,3499020752,2949064160,2386320175,2390070455,2415321851,4061277028,2290661394,2416832540,1336762016,1754252060,3520065937,3014181293,791618072,3188594551,3933548030,2332172193,3852520463,3043980520,413987798,3465142937,3030929376,4245938359,2093235073,3534596313,375366246,2157278981,2479649556,555357303,3870105701,2008414854,3344188149,4221384143,3956125452,2067696032,3594591187,2921233993,2428461,544322398,577241275,1471733935,610547355,4027169054,1432588573,1507829418,2025931657,3646575487,545086370,48609733,2200306550,1653985193,298326376,1316178497,3007786442,2064951626,458293330,2589141269,3591329599,3164325604,727753846,2179363840,146436021,1461446943,4069977195,705550613,3059967265,3887724982,4281599278,3313849956,1404054877,2845806497,146425753,1854211946]),new Uint32Array([1266315497,3048417604,3681880366,3289982499,290971e4,1235738493,2632868024,2414719590,3970600049,1771706367,1449415276,3266420449,422970021,1963543593,2690192192,3826793022,1062508698,1531092325,1804592342,2583117782,2714934279,4024971509,1294809318,4028980673,1289560198,2221992742,1669523910,35572830,157838143,1052438473,1016535060,1802137761,1753167236,1386275462,3080475397,2857371447,1040679964,2145300060,2390574316,1461121720,2956646967,4031777805,4028374788,33600511,2920084762,1018524850,629373528,3691585981,3515945977,2091462646,2486323059,586499841,988145025,935516892,3367335476,2599673255,2839830854,265290510,3972581182,2759138881,3795373465,1005194799,847297441,406762289,1314163512,1332590856,1866599683,4127851711,750260880,613907577,1450815602,3165620655,3734664991,3650291728,3012275730,3704569646,1427272223,778793252,1343938022,2676280711,2052605720,1946737175,3164576444,3914038668,3967478842,3682934266,1661551462,3294938066,4011595847,840292616,3712170807,616741398,312560963,711312465,1351876610,322626781,1910503582,271666773,2175563734,1594956187,70604529,3617834859,1007753275,1495573769,4069517037,2549218298,2663038764,504708206,2263041392,3941167025,2249088522,1514023603,1998579484,1312622330,694541497,2582060303,2151582166,1382467621,776784248,2618340202,3323268794,2497899128,2784771155,503983604,4076293799,907881277,423175695,432175456,1378068232,4145222326,3954048622,3938656102,3820766613,2793130115,2977904593,26017576,3274890735,3194772133,1700274565,1756076034,4006520079,3677328699,720338349,1533947780,354530856,688349552,3973924725,1637815568,332179504,3949051286,53804574,2852348879,3044236432,1282449977,3583942155,3416972820,4006381244,1617046695,2628476075,3002303598,1686838959,431878346,2686675385,1700445008,1080580658,1009431731,832498133,3223435511,2605976345,2271191193,2516031870,1648197032,4164389018,2548247927,300782431,375919233,238389289,3353747414,2531188641,2019080857,1475708069,455242339,2609103871,448939670,3451063019,1395535956,2413381860,1841049896,1491858159,885456874,4264095073,4001119347,1565136089,3898914787,1108368660,540939232,1173283510,2745871338,3681308437,4207628240,3343053890,4016749493,1699691293,1103962373,3625875870,2256883143,3830138730,1031889488,3479347698,1535977030,4236805024,3251091107,2132092099,1774941330,1199868427,1452454533,157007616,2904115357,342012276,595725824,1480756522,206960106,497939518,591360097,863170706,2375253569,3596610801,1814182875,2094937945,3421402208,1082520231,3463918190,2785509508,435703966,3908032597,1641649973,2842273706,3305899714,1510255612,2148256476,2655287854,3276092548,4258621189,236887753,3681803219,274041037,1734335097,3815195456,3317970021,1899903192,1026095262,4050517792,356393447,2410691914,3873677099,3682840055]),new Uint32Array([3913112168,2491498743,4132185628,2489919796,1091903735,1979897079,3170134830,3567386728,3557303409,857797738,1136121015,1342202287,507115054,2535736646,337727348,3213592640,1301675037,2528481711,1895095763,1721773893,3216771564,62756741,2142006736,835421444,2531993523,1442658625,3659876326,2882144922,676362277,1392781812,170690266,3921047035,1759253602,3611846912,1745797284,664899054,1329594018,3901205900,3045908486,2062866102,2865634940,3543621612,3464012697,1080764994,553557557,3656615353,3996768171,991055499,499776247,1265440854,648242737,3940784050,980351604,3713745714,1749149687,3396870395,4211799374,3640570775,1161844396,3125318951,1431517754,545492359,4268468663,3499529547,1437099964,2702547544,3433638243,2581715763,2787789398,1060185593,1593081372,2418618748,4260947970,69676912,2159744348,86519011,2512459080,3838209314,1220612927,3339683548,133810670,1090789135,1078426020,1569222167,845107691,3583754449,4072456591,1091646820,628848692,1613405280,3757631651,526609435,236106946,48312990,2942717905,3402727701,1797494240,859738849,992217954,4005476642,2243076622,3870952857,3732016268,765654824,3490871365,2511836413,1685915746,3888969200,1414112111,2273134842,3281911079,4080962846,172450625,2569994100,980381355,4109958455,2819808352,2716589560,2568741196,3681446669,3329971472,1835478071,660984891,3704678404,4045999559,3422617507,3040415634,1762651403,1719377915,3470491036,2693910283,3642056355,3138596744,1364962596,2073328063,1983633131,926494387,3423689081,2150032023,4096667949,1749200295,3328846651,309677260,2016342300,1779581495,3079819751,111262694,1274766160,443224088,298511866,1025883608,3806446537,1145181785,168956806,3641502830,3584813610,1689216846,3666258015,3200248200,1692713982,2646376535,4042768518,1618508792,1610833997,3523052358,4130873264,2001055236,3610705100,2202168115,4028541809,2961195399,1006657119,2006996926,3186142756,1430667929,3210227297,1314452623,4074634658,4101304120,2273951170,1399257539,3367210612,3027628629,1190975929,2062231137,2333990788,2221543033,2438960610,1181637006,548689776,2362791313,3372408396,3104550113,3145860560,296247880,1970579870,3078560182,3769228297,1714227617,3291629107,3898220290,166772364,1251581989,493813264,448347421,195405023,2709975567,677966185,3703036547,1463355134,2715995803,1338867538,1343315457,2802222074,2684532164,233230375,2599980071,2000651841,3277868038,1638401717,4028070440,3237316320,6314154,819756386,300326615,590932579,1405279636,3267499572,3150704214,2428286686,3959192993,3461946742,1862657033,1266418056,963775037,2089974820,2263052895,1917689273,448879540,3550394620,3981727096,150775221,3627908307,1303187396,508620638,2975983352,2726630617,1817252668,1876281319,1457606340,908771278,3720792119,3617206836,2455994898,1729034894,1080033504]),new Uint32Array([976866871,3556439503,2881648439,1522871579,1555064734,1336096578,3548522304,2579274686,3574697629,3205460757,3593280638,3338716283,3079412587,564236357,2993598910,1781952180,1464380207,3163844217,3332601554,1699332808,1393555694,1183702653,3581086237,1288719814,691649499,2847557200,2895455976,3193889540,2717570544,1781354906,1676643554,2592534050,3230253752,1126444790,2770207658,2633158820,2210423226,2615765581,2414155088,3127139286,673620729,2805611233,1269405062,4015350505,3341807571,4149409754,1057255273,2012875353,2162469141,2276492801,2601117357,993977747,3918593370,2654263191,753973209,36408145,2530585658,25011837,3520020182,2088578344,530523599,2918365339,1524020338,1518925132,3760827505,3759777254,1202760957,3985898139,3906192525,674977740,4174734889,2031300136,2019492241,3983892565,4153806404,3822280332,352677332,2297720250,60907813,90501309,3286998549,1016092578,2535922412,2839152426,457141659,509813237,4120667899,652014361,1966332200,2975202805,55981186,2327461051,676427537,3255491064,2882294119,3433927263,1307055953,942726286,933058658,2468411793,3933900994,4215176142,1361170020,2001714738,2830558078,3274259782,1222529897,1679025792,2729314320,3714953764,1770335741,151462246,3013232138,1682292957,1483529935,471910574,1539241949,458788160,3436315007,1807016891,3718408830,978976581,1043663428,3165965781,1927990952,4200891579,2372276910,3208408903,3533431907,1412390302,2931980059,4132332400,1947078029,3881505623,4168226417,2941484381,1077988104,1320477388,886195818,18198404,3786409e3,2509781533,112762804,3463356488,1866414978,891333506,18488651,661792760,1628790961,3885187036,3141171499,876946877,2693282273,1372485963,791857591,2686433993,3759982718,3167212022,3472953795,2716379847,445679433,3561995674,3504004811,3574258232,54117162,3331405415,2381918588,3769707343,4154350007,1140177722,4074052095,668550556,3214352940,367459370,261225585,2610173221,4209349473,3468074219,3265815641,314222801,3066103646,3808782860,282218597,3406013506,3773591054,379116347,1285071038,846784868,2669647154,3771962079,3550491691,2305946142,453669953,1268987020,3317592352,3279303384,3744833421,2610507566,3859509063,266596637,3847019092,517658769,3462560207,3443424879,370717030,4247526661,2224018117,4143653529,4112773975,2788324899,2477274417,1456262402,2901442914,1517677493,1846949527,2295493580,3734397586,2176403920,1280348187,1908823572,3871786941,846861322,1172426758,3287448474,3383383037,1655181056,3139813346,901632758,1897031941,2986607138,3066810236,3447102507,1393639104,373351379,950779232,625454576,3124240540,4148612726,2007998917,544563296,2244738638,2330496472,2058025392,1291430526,424198748,50039436,29584100,3605783033,2429876329,2791104160,1057563949,3255363231,3075367218,3463963227,1469046755,985887462])];for(let e=0,t=0;e<18;++e){var r=i[t++%i.length],s=i[t++%i.length],a=i[t++%i.length],n=i[t++%i.length];this.m_p[e]^=r<<24|s<<16|a<<8|n}let o=0,l=0;for(let e=0;e<18;)[o,l]=this._encrypt(o,l),this.m_p[e++]=o,this.m_p[e++]=l;for(let t=0;t<4;++t)for(let e=0;e<256;)[o,l]=this._encrypt(o,l),this.m_s[t][e++]=o,this.m_s[t][e++]=l}encrypt(e){return this.runCipher(e,this._encrypt.bind(this))}decrypt(e){return this.runCipher(e,this._decrypt.bind(this))}runCipher(e,t){let i=new Uint32Array(e.length),r=e.length/2|0,s=0;for(;0<r--;){var a=swapBytes(e[s]),n=swapBytes(e[s+1]);[a,n]=t(a,n),i[s++]=swapBytes(a),i[s++]=swapBytes(n)}return i}_encrypt(e,t){let i=e,r=t;i^=this.m_p[0];let s=!1;for(let e=1;e<=16;e++,s=!s)s?i=this.round(i,r,e):r=this.round(r,i,e);return r^=this.m_p[17],[r,i]}_decrypt(e,t){let i=e,r=t;i^=this.m_p[17];let s=!1;for(let e=16;1<=e;e--,s=!s)s?i=this.round(i,r,e):r=this.round(r,i,e);return r^=this.m_p[0],[r,i]}s(e,t){return this.m_s[t][e>>(3-t<<3)&255]}bf_f(e){return(this.s(e,0)+this.s(e,1)>>>0^this.s(e,2))+this.s(e,3)>>>0}round(e,t,i){return e^(this.bf_f(t)^this.m_p[i])}}const pubkeyStr="AihRvNoIbTn85FZRYNZRcT+i6KpU+maCsEqr3Q5q+LDB5tH7Tz2qQ38V",char2num=new Int8Array([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1]);class PublicKey{constructor(){this.key1=new Uint32Array(64),this.key2=new Uint32Array(64)}}class BlowfishKey{constructor(){this.pubkey=new PublicKey,this.glob1=new Uint32Array(64),this.glob2=new Uint32Array(130),this.glob1_hi=new Uint32Array(4),this.glob1_hi_inv=new Uint32Array(4)}init_bignum(t,e,i){for(let e=0;e<i;e++)t[e]=0;t[0]=e}move_key_to_big(e,t,i,r){let s;s=0!=(128&t[0])?255:0;const a=new Uint8Array(e.buffer,e.byteOffset);let n=4*r;for(;n>i;n--)a[n-1]=s;for(;0<n;n--)a[n-1]=t[i-n]}key_to_bignum(e,t,i){let r,s,a=0;if(2===t[a]){if(a++,0!=(128&t[a])){for(r=0,s=0;s<(127&t[a]);s++)r=(r<<8>>>0|t[a+s+1])>>>0;a+=1+(127&t[a])}else r=t[a],a++;r<=4*i&&this.move_key_to_big(e,t.subarray(a),r,i)}}len_bignum(e,t){let i=t-1;for(;0<=i&&0===e[i];)i--;return i+1}bitlen_bignum(e,t){var i;let r,s;if(0===(i=this.len_bignum(e,t)))return 0;for(r=32*i,s=2147483648;0==(s&e[i-1]);)s>>>=1,r--;return r}init_pubkey(){let e=0,t;var i;const r=new Uint8Array(256);for(this.init_bignum(this.pubkey.key2,65537,64),t=0;e<pubkeyStr.length;)i=(((char2num[pubkeyStr.charCodeAt(e++)]>>>0<<6>>>0|255&char2num[pubkeyStr.charCodeAt(e++)])>>>0<<6>>>0|255&char2num[pubkeyStr.charCodeAt(e++)])>>>0<<6>>>0|255&char2num[pubkeyStr.charCodeAt(e++)])>>>0,r[t++]=i>>16&255,r[t++]=i>>8&255,r[t++]=255&i;this.key_to_bignum(this.pubkey.key1,r,64),this.pubkey.len=this.bitlen_bignum(this.pubkey.key1,64)-1}len_predata(){var e=(this.pubkey.len-1)/8|0;return(1+(55/e|0))*(1+e)>>>0}cmp_bignum(e,t,i){for(;0<i;){if(e[--i]<t[i])return-1;if(e[i]>t[i])return 1}return 0}mov_bignum(t,i,r){for(let e=0;e<r;e++)t[e]=i[e]}shr_bignum(e,t,i){let r;var s=t/32|0;if(0<s){for(r=0;r<i-s;r++)e[r]=e[r+s];for(;r<i;r++)e[r]=0;t%=32}if(0!==t){for(r=0;r<i-1;r++)e[r]=(e[r]>>>t|e[r+1]<<32-t>>>0)>>>0;e[r]=e[r]>>>t}}shl_bignum(e,t,i){let r;var s=t/32|0;if(0<s){for(r=i-1;r>s;r--)e[r]=e[r-s];for(;0<r;r--)e[r]=0;t%=32}if(0!==t){for(r=i-1;0<r;r--)e[r]=(e[r]<<t>>>0|e[r-1]>>>32-t)>>>0;e[0]=e[0]<<t>>>0}}sub_bignum(e,t,i,r,s){var a,n;s+=s;var o=new Uint16Array(t.buffer,t.byteOffset),l=new Uint16Array(i.buffer,i.byteOffset);const h=new Uint16Array(e.buffer,e.byteOffset);let c=0;for(;-1!=--s;)a=o[c],n=l[c],h[c]=a-n-r&65535,r=0!=(a-n-r&65536)?1:0,c++;return r}sub_bignum_word(e,t,i,r,s){var a,n;let o=0;for(;-1!=--s;)a=t[o],n=i[o],e[o]=a-n-r&65535,r=0!=(a-n-r&65536)?1:0,o++;return r}inv_bignum(e,t,i){const r=new Uint32Array(64);var s;let a,n,o=0;for(this.init_bignum(r,0,i),this.init_bignum(e,0,i),n=this.bitlen_bignum(t,i),a=1<<n%32>>>0,o=((n+32)/32|0)-1,s=4*((n-1)/32|0)>>>0,r[s/4|0]=r[s/4|0]|1<<(n-1&31)>>>0;0<n;)n--,this.shl_bignum(r,1,i),-1!==this.cmp_bignum(r,t,i)&&(this.sub_bignum(r,r,t,0,i),e[o]=e[o]|a>>>0),a>>>=1,0===a&&(o--,a=2147483648);this.init_bignum(r,0,i)}inc_bignum(e,t){let i=0;for(;0==++e[i]&&0<--t;)i++}init_two_dw(e,t){this.mov_bignum(this.glob1,e,t),this.glob1_bitlen=this.bitlen_bignum(this.glob1,t),this.glob1_len_x2=(this.glob1_bitlen+15)/16|0,this.mov_bignum(this.glob1_hi,this.glob1.subarray(this.len_bignum(this.glob1,t)-2),2),this.glob1_hi_bitlen=this.bitlen_bignum(this.glob1_hi,2)-32>>>0,this.shr_bignum(this.glob1_hi,this.glob1_hi_bitlen,2),this.inv_bignum(this.glob1_hi_inv,this.glob1_hi,2),this.shr_bignum(this.glob1_hi_inv,1,2),this.glob1_hi_bitlen=(this.glob1_hi_bitlen+15)%16+1>>>0,this.inc_bignum(this.glob1_hi_inv,2),32<this.bitlen_bignum(this.glob1_hi_inv,2)&&(this.shr_bignum(this.glob1_hi_inv,1,2),this.glob1_hi_bitlen--),this.glob1_hi_inv_lo=65535&this.glob1_hi_inv[0],this.glob1_hi_inv_hi=this.glob1_hi_inv[0]>>>16&65535}mul_bignum_word(e,t,i,r){let s,a;var n=new Uint16Array(t.buffer,t.byteOffset);let o=a=0;for(s=0;s<r;s++)a=i*n[o]+e[o]+a,e[o]=65535&a,o++,a>>>=16;e[o]+=65535&a}mul_bignum(e,t,i,r){let s;var a=new Uint16Array(i.buffer,i.byteOffset);let n=new Uint16Array(e.buffer,e.byteOffset);this.init_bignum(e,0,2*r);let o=0;for(s=0;s<2*r;s++)this.mul_bignum_word(n.subarray(o),t,a[o],2*r),o++}not_bignum(e,t){let i;for(i=0;i<t;i++)e[i]=~e[i]>>>0}neg_bignum(e,t){this.not_bignum(e,t),this.inc_bignum(e,t)}get_mulword(e,t){let i=((((65535&(65535^e[t-1]))*this.glob1_hi_inv_lo+65536>>>1)+((65535^e[t-2])*this.glob1_hi_inv_hi+this.glob1_hi_inv_hi>>>1)+1>>>16)+((65535&(65535^e[t-1]))*this.glob1_hi_inv_hi>>>1)+((65535^e[t])*this.glob1_hi_inv_lo>>>1)+1>>>14)+this.glob1_hi_inv_hi*(65535^e[t])*2>>>this.glob1_hi_bitlen>>>0;return 65535<i&&(i=65535),65535&i}dec_bignum(e,t){let i=0;for(;--e[i]>>>0==4294967295&&0<--t;)i++}calc_a_bignum(e,t,r,s){let a;var n=this.glob1,o=this.glob2;if(this.mul_bignum(this.glob2,t,r,s),this.glob2[2*s]=0,(r=2*this.len_bignum(this.glob2,2*s+1))>=this.glob1_len_x2){this.inc_bignum(this.glob2,2*s+1),this.neg_bignum(this.glob2,2*s+1),a=1+r-this.glob1_len_x2;let e=new Uint16Array(o.buffer),t=a,i=1+r;for(;0!==a;a--){i--;var l=this.get_mulword(e,i);t--;var h=e.subarray(t);0<l&&(this.mul_bignum_word(h,this.glob1,l,2*s),0==(32768&e[i])&&0!==this.sub_bignum_word(h,h,new Uint16Array(n.buffer),0,2*s)&&e[i]--)}this.neg_bignum(this.glob2,s),this.dec_bignum(this.glob2,s)}this.mov_bignum(e,this.glob2,s)}clear_tmp_vars(e){this.init_bignum(this.glob1,0,e),this.init_bignum(this.glob2,0,e),this.init_bignum(this.glob1_hi_inv,0,4),this.init_bignum(this.glob1_hi,0,4),this.glob1_bitlen=0,this.glob1_hi_bitlen=0,this.glob1_len_x2=0,this.glob1_hi_inv_lo=0,this.glob1_hi_inv_hi=0}calc_a_key(e,t,i,r,s){var a,n=new Uint32Array(64);let o,l,h=0;for(this.init_bignum(e,1,s),a=this.len_bignum(r,s),this.init_two_dw(r,a),o=this.bitlen_bignum(i,a)<<24>>24,r=((o+31)/32|0)>>>0,l=1<<(o-1)%32>>>1,h+=r-1,o--,this.mov_bignum(e,t,a);-1!=--o;)0===l&&(l=2147483648,h--),this.calc_a_bignum(n,e,e,a),0!=(i[h]&l)?this.calc_a_bignum(e,n,t,a):this.mov_bignum(e,n,a),l>>>=1;this.init_bignum(n,0,a),this.clear_tmp_vars(s)}memcpy(e,t,i){let r=0;for(;0!=i--;)e[r]=t[r],r++}process_predata(e,t,i){var r=new Uint32Array(64),s=new Uint32Array(64);let a=0,n=0;for(var o=(this.pubkey.len-1)/8|0;1+o<=t;)this.init_bignum(r,0,64),this.memcpy(new Uint8Array(r.buffer),e.subarray(a),1+o),this.calc_a_key(s,r,this.pubkey.key2,this.pubkey.key1,64),this.memcpy(i.subarray(n),new Uint8Array(s.buffer),o),t-=1+o,a+=1+o,n+=o}decryptKey(e){this.init_pubkey();let t=new Uint8Array(256);return this.process_predata(e,this.len_predata(),t),t.subarray(0,56)}}class Crc32{static calculateCrc(i,e=4294967295){let r=e;for(let e=0,t=i.length;e<t;e++)r=(r>>>8^this.lookUp[255&r^i[e]])>>>0;return r=(r^e)>>>0,r}constructor(e=4294967295){this.polynomal=e,this.crc=e}append(i){for(let e=0,t=i.length;e<t;e++)this.crc=(this.crc>>>8^Crc32.lookUp[255&this.crc^i[e]])>>>0}get(){return(this.crc^this.polynomal)>>>0}}Crc32.lookUp=new Uint32Array([0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117]);class MixEntry{static hashFilename(t){var i=(t=t.toUpperCase()).length,r=i>>2;if(0!=(3&i)){t+=String.fromCharCode(i-(r<<2));let e=3-(3&i);for(;0!=e--;)t+=t[r<<2]}return Crc32.calculateCrc(binaryStringToUint8Array(t))}constructor(e,t,i){this.hash=e,this.offset=t,this.length=i}}MixEntry.size=12,function(e){e[e.Checksum=65536]="Checksum",e[e.Encrypted=131072]="Encrypted"}(MixFileFlags=MixFileFlags||{});class MixFile{constructor(e){this.stream=e,this.headerStart=84,this.index=new Map,this.parseHeader()}parseHeader(){var e=this.stream.readUint32(),t=0==(e&~(MixFileFlags.Checksum|MixFileFlags.Encrypted));if(t){if(0!=(e&MixFileFlags.Encrypted))return void(this.dataStart=this.parseRaHeader())}else this.stream.seek(0);this.dataStart=this.parseTdHeader(this.stream)}parseRaHeader(){const e=this.stream;var t=e.readUint8Array(80),i=(new BlowfishKey).decryptKey(t),r=e.readUint32Array(2);const s=new Blowfish(i);let a=new DataStream(s.decrypt(r));t=a.readUint16();a.readUint32(),e.position=this.headerStart;i=6+t*MixEntry.size,t=(3+i)/4|0,r=e.readUint32Array(t+t%2);a=new DataStream(s.decrypt(r));i=this.headerStart+i+(1+(~i>>>0)&7);return this.parseTdHeader(a),i}parseTdHeader(t){var i=t.readUint16();t.readUint32();for(let e=0;e<i;e++){var r=new MixEntry(t.readUint32(),t.readUint32(),t.readUint32());this.index.set(r.hash,r)}return t.position}containsFile(e){return this.index.has(MixEntry.hashFilename(e))}openFile(e){var t=this.index.get(MixEntry.hashFilename(e));if(!t)throw new Error(`File "${e}" not found`);return VirtualFile.factory(this.stream,e,this.dataStart+t.offset,t.length)}}!function(e){e[e.AutoDetect=0]="AutoDetect",e[e.TiberianSun=1]="TiberianSun",e[e.Firestorm=2]="Firestorm",e[e.RedAlert2=3]="RedAlert2",e[e.YurisRevenge=4]="YurisRevenge"}(EngineType=EngineType||{});class FileNotFoundError extends Error{constructor(){super(...arguments),this.name="FileNotFoundError"}}class MemArchive{constructor(){this.entries=new Map}addFile(e){this.entries.set(e.filename,e)}containsFile(e){return this.entries.has(e)}openFile(e){if(!this.containsFile(e))throw new Error(`File "${e}" not found`);return this.entries.get(e)}}class VirtualFileSystem{constructor(e,t){this.rfs=e,this.logger=t,this.allArchives=new Map,this.archivesByPriority=[]}fileExists(e){for(const t of this.archivesByPriority)if(t.containsFile(e))return!0;return!1}openFile(e){for(const t of this.archivesByPriority)if(t.containsFile(e))return t.openFile(e);throw new FileNotFoundError(`File "${e}" not found in VFS`)}addArchive(e,t){this.allArchives.has(t)||(this.allArchives.set(t,e),this.archivesByPriority.push(e)),this.logger.info(`Added archive "${t}" to VFS`)}hasArchive(e){return this.allArchives.has(e)}removeArchive(e){var t=this.allArchives.get(e);t&&(this.allArchives.delete(e),this.archivesByPriority.splice(this.archivesByPriority.indexOf(t),1),this.logger.info(`Removed archive "${e}" from VFS`))}listArchives(){return[...this.allArchives.keys()]}async addMixFile(e){await this.addArchiveByFilename(e,e=>new MixFile(e.stream))}async addBagFile(e){const i=await this.openFileWithRfs(e.replace(".bag",".idx"));await this.addArchiveByFilename(e,e=>{var t=new IdxFile(i.stream);return(new AudioBagFile).fromVirtualFile(e,t)})}async addArchiveByFilename(e,t){var i;this.allArchives.has(e)||(i=await this.openFileWithRfs(e))&&this.addArchive(t(i),e)}async openFileWithRfs(e){let t;try{t=await this.rfs.openFile(e)}catch(e){if(!(e instanceof FileNotFoundError))throw e}if(!t){if(!this.fileExists(e))throw new FileNotFoundError(`File "${e}" not found`);t=this.openFile(e)}return t}async loadImplicitMixFiles(e){this.logger.info("Initializing implicit mix files..."),e===EngineType.YurisRevenge&&await this.addMixFile("langmd.mix"),await this.addMixFile("language.mix"),e===EngineType.YurisRevenge&&await this.addMixFile("ra2md.mix"),await this.addMixFile("ra2.mix"),e===EngineType.YurisRevenge&&await this.addMixFile("cachemd.mix"),await this.addMixFile("cache.mix"),e===EngineType.YurisRevenge&&await this.addMixFile("loadmd.mix"),await this.addMixFile("load.mix"),e===EngineType.YurisRevenge&&await this.addMixFile("localmd.mix"),await this.addMixFile("local.mix"),e===EngineType.YurisRevenge&&await this.addMixFile("ntrlmd.mix"),await this.addMixFile("neutral.mix"),e===EngineType.YurisRevenge&&await this.addMixFile("audiomd.mix"),await this.addMixFile("audio.mix"),await this.addBagFile("audio.bag"),e===EngineType.YurisRevenge&&await this.addMixFile("conqmd.mix"),await this.addMixFile("conquer.mix"),e===EngineType.YurisRevenge&&await this.addMixFile("genermd.mix"),await this.addMixFile("generic.mix"),e===EngineType.YurisRevenge&&await this.addMixFile("isogenmd.mix"),await this.addMixFile("isogen.mix"),e===EngineType.YurisRevenge&&await this.addMixFile("cameomd.mix"),await this.addMixFile("cameo.mix"),e===EngineType.YurisRevenge&&await this.addMixFile("multimd.mix"),await this.addMixFile("multi.mix")}async loadExtraMixFiles(i){let r=new Set;for await(var e of this.rfs.getEntries())r.add(e.toLowerCase());for(var s of["ecache","expand","elocal"])for(let t=99;0<=t;t--){let e=[""+s+pad(t,"00")+".mix"];i===EngineType.YurisRevenge&&e.push(`${s}md${pad(t,"00")}.mix`);for(var a of e)r.has(a)&&await this.addMixFile(a)}let t=[".mmx"];i===EngineType.YurisRevenge&&t.push(".yro");for(const n of t)for(const o of r)o.endsWith(n)&&this.addArchive(new MixFile((await this.rfs.openFile(o)).stream),o)}async loadStandaloneFiles(e){let i=["ini","csf"],r=new Set(e?.exclude),s=[];for await(var a of this.rfs.getEntries()){let t=a.toLowerCase();i.some(e=>t.endsWith("."+e))&&!r.has(t)&&s.push(await this.rfs.openFile(a,!0))}if(s.length){let e=new MemArchive;for(var t of s)e.addFile(t);this.addArchive(e,"mem.archive")}}}class StorageQuotaError extends Error{constructor(e){super("Storage quota exceeded",e),this.name="StorageQuotaError"}}class NameNotAllowedError extends IOError{constructor(){super(...arguments),this.name="NameNotAllowedError"}}class RealFileSystemDir{constructor(e,t=!1){this.handle=e,this.caseSensitive=t}get name(){return this.handle.name}async*getEntries(){try{for await(var e of this.handle.keys())yield e}catch(e){if("NotFoundError"===e.name)throw new FileNotFoundError(`Directory "${this.handle.name}" not found`,{cause:e});if(e instanceof DOMException)throw new IOError(`Directory "${this.handle.name}" could not be read (${e.name})`,{cause:e});throw e}}async listEntries(){let e=[];for await(var t of this.getEntries())e.push(t);return e}async*getFileHandles(){try{for await(const e of this.handle.values())"file"===e.kind&&(yield e)}catch(e){if("NotFoundError"===e.name)throw new FileNotFoundError(`Directory "${this.handle.name}" not found`,{cause:e});if(e instanceof DOMException)throw new IOError(`Directory "${this.handle.name}" could not be read (${e.name})`,{cause:e});throw e}}async*getRawFiles(){for await(const e of this.getFileHandles())yield await e.getFile()}async containsEntry(e){return void 0!==await this.resolveEntryName(e)}async resolveEntryName(e){if(this.caseSensitive)return(await this.handle.getFileHandle(e).catch(()=>this.handle.getDirectoryHandle(e)).catch(()=>{}))?.name;for await(const t of this.getEntries())if(equalsIgnoreCase(t,e))return t}async fixEntryCase(e){if(!this.caseSensitive)for await(var t of this.getEntries())if(equalsIgnoreCase(t,e)){e=t;break}return e}async getRawFile(t,e=!1,i){let r;try{var s=e?t:await this.fixEntryCase(t);r=await this.handle.getFileHandle(s)}catch(e){if("NotFoundError"===e.name)throw new FileNotFoundError(`File "${t}" not found in directory "${this.handle.name}"`,{cause:e});if(e instanceof TypeError&&e.message.includes("not allowed"))throw new NameNotAllowedError(`File name "${t}" is not allowed`,{cause:e});if(e instanceof DOMException)throw new IOError(`File "${t}" could not be read (${e.name})`,{cause:e});throw e}t=await r.getFile();return i?new File([t],t.name,{type:i}):t}async openFile(e,t=!1){t=await this.getRawFile(e,t);return VirtualFile.fromRealFile(t)}async writeFile(i,r){r=r??(i instanceof File?i.name:i.filename);try{var s=await this.fixEntryCase(r);await this.deleteFile(s,!0);let e=await this.handle.getFileHandle(s,{create:!0}),t=await e.createWritable();try{await t.write(i instanceof File?i:new Uint8Array(i.stream.buffer,i.stream.byteOffset,i.stream.byteLength)),await t.close()}catch(e){throw await t.abort(),e}}catch(e){if("QuotaExceededError"===e.name)throw new StorageQuotaError({cause:e});if("NotFoundError"===e.name)throw new FileNotFoundError(`Directory "${this.handle.name}" not found`,{cause:e});if(e instanceof TypeError&&e.message.includes("not allowed"))throw new NameNotAllowedError(`File name "${r}" is not allowed`,{cause:e});if(e instanceof DOMException)throw new IOError(`File "${r}" could not be written (${e.name})`,{cause:e});throw e}}async deleteFile(t,i=!1){t=i?t:await this.resolveEntryName(t);if(t)try{await this.handle.removeEntry(t)}catch(e){if(i&&"NotFoundError"===e.name)return;if("QuotaExceededError"===e.name)throw new StorageQuotaError({cause:e});if(e instanceof TypeError&&e.message.includes("not allowed"))throw new NameNotAllowedError(`File name "${t}" is not allowed`,{cause:e});if(e instanceof DOMException)throw new IOError(`File "${t}" could not be deleted (${e.name})`,{cause:e});throw e}}async getDirectory(t,e=this.caseSensitive){var i=e?t:await this.fixEntryCase(t);let r;try{r=await this.handle.getDirectoryHandle(i)}catch(e){if("NotFoundError"===e.name)throw new FileNotFoundError(`Directory "${t}" not found or parent directory "${this.handle.name}" is gone`,{cause:e});if(e instanceof TypeError&&e.message.includes("not allowed"))throw new NameNotAllowedError(`Directory name "${t}" is not allowed`,{cause:e});if(e instanceof DOMException)throw new IOError(`Directory "${t}" could not be read (${e.name})`,{cause:e});throw e}return new RealFileSystemDir(r,e)}async getOrCreateDirectory(t,e=this.caseSensitive){var i=e?t:await this.fixEntryCase(t);try{return new RealFileSystemDir(await this.handle.getDirectoryHandle(i,{create:!0}),e)}catch(e){if("QuotaExceededError"===e.name)throw new StorageQuotaError({cause:e});if("NotFoundError"===e.name)throw new FileNotFoundError(`Directory "${this.handle.name}" not found"`,{cause:e});if(e instanceof TypeError&&e.message.includes("not allowed"))throw new NameNotAllowedError(`Directory name "${t}" is not allowed`,{cause:e});if(e instanceof DOMException)throw new IOError(`Directory "${t}" could not be created (${e.name})`,{cause:e});throw e}}async deleteDirectory(t,e=!1){t=await this.resolveEntryName(t);if(t)try{await this.handle.removeEntry(t,{recursive:e})}catch(e){if("QuotaExceededError"===e.name)throw new StorageQuotaError({cause:e});if("InvalidModificationError"===e.name)throw new IOError("Can't delete non-empty directory when recursive = false");if(e instanceof TypeError&&e.message.includes("not allowed"))throw new NameNotAllowedError(`Directory name "${t}" is not allowed`,{cause:e});if(e instanceof DOMException)throw new IOError(`Directory "${t}" could not be deleted (${e.name})`,{cause:e});throw e}}}class RealFileSystem{constructor(){this.directories=[]}addRootDirectoryHandle(e){this.rootDirectory=this.addDirectoryHandle(e),this.rootDirectoryHandle=e}getRootDirectoryHandle(){return this.rootDirectoryHandle}addDirectoryHandle(e){e=new RealFileSystemDir(e);return this.directories.push(e),e}addDirectory(e){this.directories.push(e)}async getDirectory(e){var t=await this.findDirectory(e);if(!t)throw new Error(`Directory "${e}" not found in real file system`);return t}async findDirectory(e){for(const t of this.directories)if(await t.containsEntry(e))return await t.getDirectory(e)}getRootDirectory(){return this.rootDirectory}async containsEntry(e){for(const t of this.directories)if(await t.containsEntry(e))return!0;return!1}async openFile(e,t=!1){for(const i of this.directories)try{return await i.openFile(e,t)}catch(e){if(!(e instanceof FileNotFoundError))throw e}throw new FileNotFoundError(`File "${e}" not found in real file system`)}async getRawFile(e){for(const t of this.directories)if(await t.containsEntry(e))return await t.getRawFile(e);throw new Error(`File "${e}" not found in real file system`)}async*getEntries(){for(var e of this.directories)for await(var t of e.getEntries())yield t}}class LazyResourceCollection{constructor(e){this.resourceFactory=e,this.resources=new Map}setVfs(e){this.vfs=e}set(e,t){this.resources.set(e,t)}has(e){return!!this.resources.has(e)||(this.vfs?.fileExists(e)??!1)}get(e){let t;return t=this.resources.get(e),!t&&this.vfs?.fileExists(e)&&(t=this.resourceFactory(this.vfs.openFile(e)),this.resources.set(e,t)),t}clear(e){e?this.resources.delete(e):this.resources.clear()}}const chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function encode(t){let i="";for(let e=0;e<t.length;e+=3)i+=chars[t[e]>>2],i+=chars[(3&t[e])<<4|t[e+1]>>4],i+=chars[(15&t[e+1])<<2|t[e+2]>>6],i+=chars[63&t[e+2]];return t.length%3==2?i=i.substring(0,i.length-1)+"=":t.length%3==1&&(i=i.substring(0,i.length-2)+"=="),i}function decode(i){let r=new Uint8Array(256);for(let e=0;e<chars.length;e++)r[chars.charCodeAt(e)]=e;let e=.75*i.length;"="===i[i.length-1]&&(e--,"="===i[i.length-2]&&e--);let s=new Uint8Array(e);for(let e=0,t=0;e<i.length;e+=4){var a=r[i.charCodeAt(e)],n=r[i.charCodeAt(e+1)],o=r[i.charCodeAt(e+2)],l=r[i.charCodeAt(e+3)];s[t++]=a<<2|n>>4,s[t++]=(15&n)<<4|o>>2,s[t++]=(3&o)<<6|63&l}return s}function changeBitDepth(r,e,s,t){if(-1<["32f","64"].indexOf(e)&&-1<["32f","64"].indexOf(t))s.set(r);else{validateBitDepth_(e),validateBitDepth_(t);let i=getBitDepthFunction_(e,t);var a={oldMin:Math.pow(2,parseInt(e,10))/2,newMin:Math.pow(2,parseInt(t,10))/2,oldMax:Math.pow(2,parseInt(e,10))/2-1,newMax:Math.pow(2,parseInt(t,10))/2-1};sign8Bit_(e,r,!0);for(let e=0,t=r.length;e<t;e++)s[e]=i(r[e],a);sign8Bit_(t,s,!1)}}function intToInt_(e,t){return e=0<e?parseInt(e/t.oldMax*t.newMax,10):parseInt(e/t.oldMin*t.newMin,10)}function floatToInt_(e,t){return parseInt(0<e?e*t.newMax:e*t.newMin,10)}function intToFloat_(e,t){return 0<e?e/t.oldMax:e/t.oldMin}function getBitDepthFunction_(e,t){let i=function(e){return e};return e!=t&&(i=["32f","64"].includes(e)?floatToInt_:["32f","64"].includes(t)?intToFloat_:intToInt_),i}function validateBitDepth_(e){if("32f"!=e&&"64"!=e&&(parseInt(e,10)<"8"||"53"<parseInt(e,10)))throw new Error("Invalid bit depth.")}function sign8Bit_(e,i,t){if("8"==e){var r=t?-128:128;for(let e=0,t=i.length;e<t;e++)i[e]=i[e]+=r}}const INDEX_TABLE=[-1,-1,-1,-1,2,4,6,8,-1,-1,-1,-1,2,4,6,8],STEP_TABLE=[7,8,9,10,11,12,13,14,16,17,19,21,23,25,28,31,34,37,41,45,50,55,60,66,73,80,88,97,107,118,130,143,157,173,190,209,230,253,279,307,337,371,408,449,494,544,598,658,724,796,876,963,1060,1166,1282,1411,1552,1707,1878,2066,2272,2499,2749,3024,3327,3660,4026,4428,4871,5358,5894,6484,7132,7845,8630,9493,10442,11487,12635,13899,15289,16818,18500,20350,22385,24623,27086,29794,32767];function imaadpcm_encode(i){var r={index:0,predicted:0,step:7};let s=new Uint8Array(i.length),a=[],n=0,o=0;for(let e=0,t=i.length;e<t;e++)e%505==0&&0!=e&&(s.set(encodeBlock(a,r),n),n+=256,a=[],o++),a.push(i[e]);let e=i.length/2;return e%2&&e++,s.slice(0,e+512+4*o)}function imaadpcm_decode(t,e=256){var i={index:0,predicted:0,step:7};let r=new Int16Array(2*t.length),s=[],a=0,n=t.length,o=0;for(;0<n;){var l=Math.min(n,e);for(let e=0;e<l;e++)s.push(t[o]),o++;var h=decodeBlock(s,i);r.set(h,a),a+=h.length,s=[],n-=e}return r.slice(0,a)}function encodeBlock(i,r){let s=blockHead_(i[0],r);for(let e=3,t=i.length;e<t;e+=2){var a=encodeSample_(i[e],r),n=encodeSample_(i[e+1],r);s.push(n<<4|a)}return s}function decodeBlock(i,r){r.predicted=sign_(i[1]<<8|i[0]),r.index=i[2],r.step=STEP_TABLE[r.index];let s=[r.predicted];for(let e=4,t=i.length;e<t;e++){var a=i[e],n=a>>4;s.push(decodeSample_(n<<4^a,r)),s.push(decodeSample_(n,r))}return s}function sign_(e){return 32767<e?e-65536:e}function encodeSample_(e,t){let i=e-t.predicted,r=0;0<=i?r=0:(r=8,i=-i);let s=STEP_TABLE[t.index],a=s>>3;return i>s&&(r|=4,i-=s,a+=s),s>>=1,i>s&&(r|=2,i-=s,a+=s),s>>=1,i>s&&(r|=1,a+=s),updateEncoder_(r,a,t),r}function updateEncoder_(e,t,i){8&e?i.predicted-=t:i.predicted+=t,i.predicted<-32768?i.predicted=-32768:32767<i.predicted&&(i.predicted=32767),i.index+=INDEX_TABLE[7&e],i.index<0?i.index=0:88<i.index&&(i.index=88)}function decodeSample_(e,t){let i=0;return 4&e&&(i+=t.step),2&e&&(i+=t.step>>1),1&e&&(i+=t.step>>2),i+=t.step>>3,8&e&&(i=-i),t.predicted+=i,32767<t.predicted?t.predicted=32767:t.predicted<-32768&&(t.predicted=-32768),updateDecoder_(e,t),t.predicted}function updateDecoder_(e,t){t.index+=INDEX_TABLE[e],t.index<0?t.index=0:88<t.index&&(t.index=88),t.step=STEP_TABLE[t.index]}function blockHead_(e,t){encodeSample_(e,t);let i=[];return i.push(255&e),i.push(e>>8&255),i.push(t.index),i.push(0),i}const LOG_TABLE=[1,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7];function encodeSample(e){let t;var i,r=~(e=-32768==e?-32767:e)>>8&128;return r||(e*=-1),32635<e&&(e=32635),t=256<=e?(i=LOG_TABLE[e>>8&127])<<4|e>>i+3&15:e>>4,85^t^r}function decodeSample(e){let t=0;0!=(128&(e^=85))&&(e&=-129,t=-1);var i=4+((240&e)>>4);let r=0;return r=4!=i?1<<i|(15&e)<<i-4|1<<i-5:e<<1|1,r=0===t?r:-r,8*r*-1}function alaw_encode(i){let r=new Uint8Array(i.length);for(let e=0,t=i.length;e<t;e++)r[e]=encodeSample(i[e]);return r}function alaw_decode(i){let r=new Int16Array(i.length);for(let e=0,t=i.length;e<t;e++)r[e]=decodeSample(i[e]);return r}const BIAS=132,CLIP=32635,encodeTable=[0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7],decodeTable=[0,132,396,924,1980,4092,8316,16764];function mulaw_encodeSample(e){var t=e>>8&128;return 0!=t&&(e=-e),(e+=BIAS)>CLIP&&(e=CLIP),~(t|(t=encodeTable[e>>7&255])<<4|e>>t+3&15)}function mulaw_decodeSample(e){var t,i;let r;return t=128&(e=~e),i=e>>4&7,e=15&e,r=decodeTable[i]+(e<<3+i),0!=t&&(r=-r),r}function mulaw_encode(i){let r=new Uint8Array(i.length);for(let e=0,t=i.length;e<t;e++)r[e]=mulaw_encodeSample(i[e]);return r}function mulaw_decode(i){let r=new Int16Array(i.length);for(let e=0,t=i.length;e<t;e++)r[e]=mulaw_decodeSample(i[e]);return r}function endianness(t,i,r=0,s=t.length){for(let e=r;e<s;e+=i)swap_(t,i,e)}function swap_(t,i,r){i--;for(let e=0;e<i;e++){var s=t[r+e];t[r+e]=t[r+i],t[r+i]=s,i--}}function unpack(o,e=0,t=o.length){let l="";for(let n=e;n<t;){let i=128,r=191,s=!1,a=o[n++];if(0<=a&&a<=127)l+=String.fromCharCode(a);else{let t=0;194<=a&&a<=223?t=1:224<=a&&a<=239?(t=2,224===o[n]&&(i=160),237===o[n]&&(r=159)):240<=a&&a<=244?(t=3,240===o[n]&&(i=144),244===o[n]&&(r=143)):s=!0,a&=(1<<8-t-1)-1;for(let e=0;e<t;e++)(o[n]<i||o[n]>r)&&(s=!0),a=a<<6|63&o[n],n++;s?l+=String.fromCharCode(65533):a<=65535?l+=String.fromCharCode(a):(a-=65536,l+=String.fromCharCode(55296+(a>>10&1023),56320+(1023&a)))}}return l}function pack(e,i,r=0){let s=0;for(var t=e.length;s<t;){var a=e.codePointAt(s);if(a<128)i[r]=a,r++;else{let e=0,t=0;for(a<=2047?(e=1,t=192):a<=65535?(e=2,t=224):a<=1114111&&(e=3,t=240,s++),i[r]=(a>>6*e)+t,r++;0<e;)i[r]=128|a>>6*(e-1)&63,r++,e--}s++}return r}const BYTE_POW_TABLE=new Array(8).fill(0).map((e,t)=>Math.pow(2,8*t));class IntParser{constructor(e,t=!1){this.bits=e,this.offset=Math.ceil(e/8),this.max=Math.pow(2,e)-1,this.min=0,this.unpack=this.unpack_,t&&(this.max=Math.pow(2,e)/2-1,this.min=-this.max-1,this.unpack=this.unpackSigned_)}pack(i,r,s=0){r=this.clamp_(Math.round(r));for(let e=0,t=this.offset;e<t;e++)i[s]=255&Math.floor(r/BYTE_POW_TABLE[e]),s++;return s}unpack_(t,i=0){let r=0;for(let e=0;e<this.offset;e++)r+=t[i+e]*BYTE_POW_TABLE[e];return r}unpackSigned_(e,t=0){return this.sign_(this.unpack_(e,t))}clamp_(e){return e>this.max?this.max:e<this.min?this.min:e}sign_(e){return e>this.max&&(e-=2*this.max+2),e}}class FloatParser{constructor(e,t){this.offset=Math.ceil((e+t)/8),this.ebits=e,this.fbits=t,this.bias=(1<<e-1)-1,this.biasP2=Math.pow(2,this.bias+1),this.ebitsFbits=e+t,this.fbias=Math.pow(2,-(8*this.offset-1-e))}pack(e,t,i){var r=((t=+(t=Math.abs(t)>this.biasP2-2*this.ebitsFbits?t<0?-1/0:1/0:t))||1/t)<0||t<0?1:0;t=Math.abs(t);let s=Math.min(Math.floor(Math.log(t)/Math.LN2),1023),a=roundToEven(t/Math.pow(2,s)*Math.pow(2,this.fbits));return t!=t?(a=Math.pow(2,this.fbits-1),s=(1<<this.ebits)-1):0!==t&&(t>=Math.pow(2,1-this.bias)?(2<=a/Math.pow(2,this.fbits)&&(s+=1,a=1),a=s>this.bias?(s=(1<<this.ebits)-1,0):(s+=this.bias,roundToEven(a)-Math.pow(2,this.fbits))):(a=roundToEven(t/Math.pow(2,1-this.bias-this.fbits)),s=0)),this.packFloatBits_(e,i,r,s,a)}unpack(t,i){var e=(1<<this.ebits)-1;let r,s="";for(let e=this.offset-1;0<=e;e--){var a=t[e+i].toString(2);s+="00000000".substring(a.length)+a}var n="1"==s.charAt(0)?-1:1;s=s.substring(1);let o=parseInt(s.substring(0,this.ebits),2);return s=s.substring(this.ebits),o==e?0!==parseInt(s,2)?NaN:1/0*n:(r=0===o?(o+=1,parseInt(s,2)):parseInt("1"+s,2),n*r*this.fbias*Math.pow(2,o-this.bias))}packFloatBits_(e,t,i,r,s){let a=[];a.push(i);for(let e=this.ebits;0<e;--e)a[e]=r%2?1:0,r=Math.floor(r/2);var n=a.length;for(let e=this.fbits;0<e;--e)a[n+e]=s%2?1:0,s=Math.floor(s/2);let o=a.join(""),l=this.offset+t-1,h=t;for(;l>=t;)e[l]=parseInt(o.substring(0,8),2),o=o.substring(8),l--,h++;return h}}function roundToEven(e){var t=Math.floor(e),e=e-t;return!(e<.5)&&(.5<e||t%2)?t+1:t}function unpackString(e,t=0,i=e.length){return unpack(e,t,i)}function packString(e){var t=[];return pack(e,t),t}function packStringTo(e,t,i=0){return pack(e,t,i)}function packArrayTo(e,t,i,r=0){let s=getParser_((t=t||{}).bits,t.fp,t.signed);var a=Math.ceil(t.bits/8);let n=0;for(var o=r,l=e.length;n<l;n++)r=s.pack(i,e[n],r);return t.be&&endianness(i,a,o,r),r}function unpackArrayTo(e,t,i,r=0,s=e.length){var a,n=getParser_((t=t||{}).bits,t.fp,t.signed);s=getUnpackLen_(e,r,s,n.offset),t.be?(a=copyBuffer_(e),t.be&&endianness(a,n.offset,r,s),unpack_(a,i,r,s,n)):unpack_(e,i,r,s,n)}function packTo(e,t,i,r=0){return packArrayTo([e],t,i,r)}function binary_pack(e,t){var i=[];return packTo(e,t,i,0),i}function binary_unpack(e,t,i=0){var r=[];return unpackArrayTo(e,t,r,i,i+Math.ceil(t.bits/8)),r[0]}function unpack_(i,r,s,a,n){var o=n.offset;for(let e=0,t=s;t<a;t+=o,e++)r[e]=n.unpack(i,t)}function copyBuffer_(e){return new Uint8Array(e)}function getUnpackLen_(e,t,i,r){return i-(i-t)%r}function getParser_(e,t,i){return t&&32==e?new FloatParser(8,23):t&&64==e?new FloatParser(11,52):new IntParser(e,i)}class RIFFFile{constructor(){this.container="",this.chunkSize=0,this.format="",this.signature=null,this.head=0,this.uInt32={bits:32,be:!1},this.supported_containers=["RIFF","RIFX"]}setSignature(e){if(this.head=0,this.container=this.readString(e,4),-1===this.supported_containers.indexOf(this.container))throw Error("Not a supported format.");this.uInt32.be="RIFX"===this.container,this.chunkSize=this.readUInt32(e),this.format=this.readString(e,4),this.signature={chunkId:this.container,chunkSize:this.chunkSize,format:this.format,subChunks:this.getSubChunksIndex_(e)}}findChunk(t,i=!1){var r=this.signature.subChunks;let s=[];for(let e=0;e<r.length;e++)if(r[e].chunkId==t){if(!i)return r[e];s.push(r[e])}return"LIST"==t&&s.length?s:null}readString(e,t){var i=unpackString(e,this.head,this.head+t);return this.head+=t,i}readUInt32(e){e=binary_unpack(e,this.uInt32,this.head);return this.head+=4,e}getSubChunksIndex_(e){let t=[],i=this.head;for(;i<=e.length-8;)t.push(this.getSubChunkIndex_(e,i)),i+=8+t[t.length-1].chunkSize,i=i%2?i+1:i;return t}getSubChunkIndex_(e,t){let i={chunkId:this.getChunkId_(e,t),chunkSize:this.getChunkSize_(e,t)};return"LIST"==i.chunkId?(i.format=unpackString(e,t+8,t+12),this.head+=4,i.subChunks=this.getSubChunksIndex_(e)):(e=i.chunkSize%2?i.chunkSize+1:i.chunkSize,this.head=t+8+e,i.chunkData={start:t+8,end:this.head}),i}getChunkId_(e,t){return this.head+=4,unpackString(e,t,t+4)}getChunkSize_(e,t){return this.head+=4,binary_unpack(e,this.uInt32,t+4)}}class WaveFileReader extends RIFFFile{constructor(){super(),this.supported_containers.push("RF64"),this.fmt={chunkId:"",chunkSize:0,audioFormat:0,numChannels:0,sampleRate:0,byteRate:0,blockAlign:0,bitsPerSample:0,cbSize:0,validBitsPerSample:0,dwChannelMask:0,subformat:[]},this.fact={chunkId:"",chunkSize:0,dwSampleLength:0},this.cue={chunkId:"",chunkSize:0,dwCuePoints:0,points:[]},this.smpl={chunkId:"",chunkSize:0,dwManufacturer:0,dwProduct:0,dwSamplePeriod:0,dwMIDIUnityNote:0,dwMIDIPitchFraction:0,dwSMPTEFormat:0,dwSMPTEOffset:0,dwNumSampleLoops:0,dwSamplerData:0,loops:[]},this.bext={chunkId:"",chunkSize:0,description:"",originator:"",originatorReference:"",originationDate:"",originationTime:"",timeReference:[0,0],version:0,UMID:"",loudnessValue:0,loudnessRange:0,maxTruePeakLevel:0,maxMomentaryLoudness:0,maxShortTermLoudness:0,reserved:"",codingHistory:""},this.iXML={chunkId:"",chunkSize:0,value:""},this.ds64={chunkId:"",chunkSize:0,riffSizeHigh:0,riffSizeLow:0,dataSizeHigh:0,dataSizeLow:0,originationTime:0,sampleCountHigh:0,sampleCountLow:0},this.data={chunkId:"",chunkSize:0,samples:new Uint8Array(0)},this.LIST=[],this.junk={chunkId:"",chunkSize:0,chunkData:[]},this._PMX={chunkId:"",chunkSize:0,value:""},this.uInt16={bits:16,be:!1,signed:!1,fp:!1}}fromBuffer(e,t=!0){if(this.clearHeaders(),this.setSignature(e),this.uInt16.be=this.uInt32.be,"WAVE"!=this.format)throw Error('Could not find the "WAVE" format identifier');this.readDs64Chunk_(e),this.readFmtChunk_(e),this.readFactChunk_(e),this.readBextChunk_(e),this.readiXMLChunk_(e),this.readCueChunk_(e),this.readSmplChunk_(e),this.readDataChunk_(e,t),this.readJunkChunk_(e),this.readLISTChunk_(e),this.read_PMXChunk_(e)}clearHeaders(){var e=new WaveFileReader;Object.assign(this.fmt,e.fmt),Object.assign(this.fact,e.fact),Object.assign(this.cue,e.cue),Object.assign(this.smpl,e.smpl),Object.assign(this.bext,e.bext),Object.assign(this.iXML,e.iXML),Object.assign(this.ds64,e.ds64),Object.assign(this.data,e.data),this.LIST=[],Object.assign(this.junk,e.junk),Object.assign(this._PMX,e._PMX)}readFmtChunk_(e){var t=this.findChunk("fmt ");if(!t)throw Error('Could not find the "fmt " chunk');this.head=t.chunkData.start,this.fmt.chunkId=t.chunkId,this.fmt.chunkSize=t.chunkSize,this.fmt.audioFormat=this.readUInt16_(e),this.fmt.numChannels=this.readUInt16_(e),this.fmt.sampleRate=this.readUInt32(e),this.fmt.byteRate=this.readUInt32(e),this.fmt.blockAlign=this.readUInt16_(e),this.fmt.bitsPerSample=this.readUInt16_(e),this.readFmtExtension_(e)}readFmtExtension_(e){16<this.fmt.chunkSize&&(this.fmt.cbSize=this.readUInt16_(e),18<this.fmt.chunkSize&&(this.fmt.validBitsPerSample=this.readUInt16_(e),20<this.fmt.chunkSize&&(this.fmt.dwChannelMask=this.readUInt32(e),this.fmt.subformat=[this.readUInt32(e),this.readUInt32(e),this.readUInt32(e),this.readUInt32(e)])))}readFactChunk_(e){var t=this.findChunk("fact");t&&(this.head=t.chunkData.start,this.fact.chunkId=t.chunkId,this.fact.chunkSize=t.chunkSize,this.fact.dwSampleLength=this.readUInt32(e))}readCueChunk_(t){var e=this.findChunk("cue ");if(e){this.head=e.chunkData.start,this.cue.chunkId=e.chunkId,this.cue.chunkSize=e.chunkSize,this.cue.dwCuePoints=this.readUInt32(t);for(let e=0;e<this.cue.dwCuePoints;e++)this.cue.points.push({dwName:this.readUInt32(t),dwPosition:this.readUInt32(t),fccChunk:this.readString(t,4),dwChunkStart:this.readUInt32(t),dwBlockStart:this.readUInt32(t),dwSampleOffset:this.readUInt32(t)})}}readSmplChunk_(t){var e=this.findChunk("smpl");if(e){this.head=e.chunkData.start,this.smpl.chunkId=e.chunkId,this.smpl.chunkSize=e.chunkSize,this.smpl.dwManufacturer=this.readUInt32(t),this.smpl.dwProduct=this.readUInt32(t),this.smpl.dwSamplePeriod=this.readUInt32(t),this.smpl.dwMIDIUnityNote=this.readUInt32(t),this.smpl.dwMIDIPitchFraction=this.readUInt32(t),this.smpl.dwSMPTEFormat=this.readUInt32(t),this.smpl.dwSMPTEOffset=this.readUInt32(t),this.smpl.dwNumSampleLoops=this.readUInt32(t),this.smpl.dwSamplerData=this.readUInt32(t);for(let e=0;e<this.smpl.dwNumSampleLoops;e++)this.smpl.loops.push({dwName:this.readUInt32(t),dwType:this.readUInt32(t),dwStart:this.readUInt32(t),dwEnd:this.readUInt32(t),dwFraction:this.readUInt32(t),dwPlayCount:this.readUInt32(t)})}}readDataChunk_(e,t){var i=this.findChunk("data");if(!i)throw Error('Could not find the "data" chunk');this.data.chunkId="data",this.data.chunkSize=i.chunkSize,t&&(this.data.samples=e.slice(i.chunkData.start,i.chunkData.end))}readBextChunk_(e){var t=this.findChunk("bext");t&&(this.head=t.chunkData.start,this.bext.chunkId=t.chunkId,this.bext.chunkSize=t.chunkSize,this.bext.description=this.readString(e,256),this.bext.originator=this.readString(e,32),this.bext.originatorReference=this.readString(e,32),this.bext.originationDate=this.readString(e,10),this.bext.originationTime=this.readString(e,8),this.bext.timeReference=[this.readUInt32(e),this.readUInt32(e)],this.bext.version=this.readUInt16_(e),this.bext.UMID=this.readString(e,64),this.bext.loudnessValue=this.readUInt16_(e),this.bext.loudnessRange=this.readUInt16_(e),this.bext.maxTruePeakLevel=this.readUInt16_(e),this.bext.maxMomentaryLoudness=this.readUInt16_(e),this.bext.maxShortTermLoudness=this.readUInt16_(e),this.bext.reserved=this.readString(e,180),this.bext.codingHistory=this.readString(e,this.bext.chunkSize-602))}readiXMLChunk_(e){var t=this.findChunk("iXML");t&&(this.head=t.chunkData.start,this.iXML.chunkId=t.chunkId,this.iXML.chunkSize=t.chunkSize,this.iXML.value=unpackString(e,this.head,this.head+this.iXML.chunkSize))}readDs64Chunk_(e){var t=this.findChunk("ds64");if(t)this.head=t.chunkData.start,this.ds64.chunkId=t.chunkId,this.ds64.chunkSize=t.chunkSize,this.ds64.riffSizeHigh=this.readUInt32(e),this.ds64.riffSizeLow=this.readUInt32(e),this.ds64.dataSizeHigh=this.readUInt32(e),this.ds64.dataSizeLow=this.readUInt32(e),this.ds64.originationTime=this.readUInt32(e),this.ds64.sampleCountHigh=this.readUInt32(e),this.ds64.sampleCountLow=this.readUInt32(e);else if("RF64"==this.container)throw Error('Could not find the "ds64" chunk')}readLISTChunk_(t){var i=this.findChunk("LIST",!0);if(null!==i)for(let e=0;e<i.length;e++){var r=i[e];this.LIST.push({chunkId:r.chunkId,chunkSize:r.chunkSize,format:r.format,subChunks:[]});for(let e=0;e<r.subChunks.length;e++)this.readLISTSubChunks_(r.subChunks[e],r.format,t)}}readLISTSubChunks_(e,t,i){"adtl"==t?-1<["labl","note","ltxt"].indexOf(e.chunkId)&&this.readLISTadtlSubChunks_(i,e):"INFO"==t&&this.readLISTINFOSubChunks_(i,e)}readLISTadtlSubChunks_(e,t){this.head=t.chunkData.start;let i={chunkId:t.chunkId,chunkSize:t.chunkSize,dwName:this.readUInt32(e)};"ltxt"==t.chunkId?(i.dwSampleLength=this.readUInt32(e),i.dwPurposeID=this.readUInt32(e),i.dwCountry=this.readUInt16_(e),i.dwLanguage=this.readUInt16_(e),i.dwDialect=this.readUInt16_(e),i.dwCodePage=this.readUInt16_(e),i.value=""):i.value=this.readZSTR_(e,this.head),this.LIST[this.LIST.length-1].subChunks.push(i)}readLISTINFOSubChunks_(e,t){this.head=t.chunkData.start,this.LIST[this.LIST.length-1].subChunks.push({chunkId:t.chunkId,chunkSize:t.chunkSize,value:this.readZSTR_(e,this.head)})}readJunkChunk_(e){var t=this.findChunk("junk");t&&(this.junk={chunkId:t.chunkId,chunkSize:t.chunkSize,chunkData:[].slice.call(e.slice(t.chunkData.start,t.chunkData.end))})}read_PMXChunk_(e){var t=this.findChunk("_PMX");t&&(this.head=t.chunkData.start,this._PMX.chunkId=t.chunkId,this._PMX.chunkSize=t.chunkSize,this._PMX.value=unpackString(e,this.head,this.head+this._PMX.chunkSize))}readZSTR_(t,i=0){for(let e=i;e<t.length&&(this.head++,0!==t[e]);e++);return unpackString(t,i,this.head-1)}readUInt16_(e){e=binary_unpack(e,this.uInt16,this.head);return this.head+=2,e}}function writeString(e,t){let i=packString(e);for(let e=i.length;e<t;e++)i.push(0);return i}class WaveFileParser extends WaveFileReader{toBuffer(){this.uInt16.be="RIFX"===this.container,this.uInt32.be=this.uInt16.be;var t=[this.getJunkBytes_(),this.getDs64Bytes_(),this.getBextBytes_(),this.getiXMLBytes_(),this.getFmtBytes_(),this.getFactBytes_(),packString(this.data.chunkId),binary_pack(this.data.samples.length,this.uInt32),this.data.samples,this.getCueBytes_(),this.getSmplBytes_(),this.getLISTBytes_(),this.get_PMXBytes_()];let i=0;for(let e=0;e<t.length;e++)i+=t[e].length;let r=new Uint8Array(i+12),s=0;s=packStringTo(this.container,r,s),s=packTo(i+4,this.uInt32,r,s),s=packStringTo(this.format,r,s);for(let e=0;e<t.length;e++)r.set(t[e],s),s+=t[e].length;return r}getBextBytes_(){let e=[];return this.enforceBext_(),this.bext.chunkId&&(this.bext.chunkSize=602+this.bext.codingHistory.length,e=e.concat(packString(this.bext.chunkId),binary_pack(602+this.bext.codingHistory.length,this.uInt32),writeString(this.bext.description,256),writeString(this.bext.originator,32),writeString(this.bext.originatorReference,32),writeString(this.bext.originationDate,10),writeString(this.bext.originationTime,8),binary_pack(this.bext.timeReference[0],this.uInt32),binary_pack(this.bext.timeReference[1],this.uInt32),binary_pack(this.bext.version,this.uInt16),writeString(this.bext.UMID,64),binary_pack(this.bext.loudnessValue,this.uInt16),binary_pack(this.bext.loudnessRange,this.uInt16),binary_pack(this.bext.maxTruePeakLevel,this.uInt16),binary_pack(this.bext.maxMomentaryLoudness,this.uInt16),binary_pack(this.bext.maxShortTermLoudness,this.uInt16),writeString(this.bext.reserved,180),writeString(this.bext.codingHistory,this.bext.codingHistory.length))),this.enforceByteLen_(e),e}enforceBext_(){for(var e in this.bext)if(this.bext.hasOwnProperty(e)&&this.bext[e]&&"timeReference"!=e){this.bext.chunkId="bext";break}(this.bext.timeReference[0]||this.bext.timeReference[1])&&(this.bext.chunkId="bext")}getiXMLBytes_(){let e=[];var t;return this.iXML.chunkId&&(t=packString(this.iXML.value),this.iXML.chunkSize=t.length,e=e.concat(packString(this.iXML.chunkId),binary_pack(this.iXML.chunkSize,this.uInt32),t)),this.enforceByteLen_(e),e}getDs64Bytes_(){let e=[];return this.ds64.chunkId&&(e=e.concat(packString(this.ds64.chunkId),binary_pack(this.ds64.chunkSize,this.uInt32),binary_pack(this.ds64.riffSizeHigh,this.uInt32),binary_pack(this.ds64.riffSizeLow,this.uInt32),binary_pack(this.ds64.dataSizeHigh,this.uInt32),binary_pack(this.ds64.dataSizeLow,this.uInt32),binary_pack(this.ds64.originationTime,this.uInt32),binary_pack(this.ds64.sampleCountHigh,this.uInt32),binary_pack(this.ds64.sampleCountLow,this.uInt32))),this.enforceByteLen_(e),e}getCueBytes_(){let e=[];var t;return this.cue.chunkId&&(t=this.getCuePointsBytes_(),e=e.concat(packString(this.cue.chunkId),binary_pack(t.length+4,this.uInt32),binary_pack(this.cue.dwCuePoints,this.uInt32),t)),this.enforceByteLen_(e),e}getCuePointsBytes_(){let t=[];for(let e=0;e<this.cue.dwCuePoints;e++)t=t.concat(binary_pack(this.cue.points[e].dwName,this.uInt32),binary_pack(this.cue.points[e].dwPosition,this.uInt32),packString(this.cue.points[e].fccChunk),binary_pack(this.cue.points[e].dwChunkStart,this.uInt32),binary_pack(this.cue.points[e].dwBlockStart,this.uInt32),binary_pack(this.cue.points[e].dwSampleOffset,this.uInt32));return t}getSmplBytes_(){let e=[];var t;return this.smpl.chunkId&&(t=this.getSmplLoopsBytes_(),e=e.concat(packString(this.smpl.chunkId),binary_pack(t.length+36,this.uInt32),binary_pack(this.smpl.dwManufacturer,this.uInt32),binary_pack(this.smpl.dwProduct,this.uInt32),binary_pack(this.smpl.dwSamplePeriod,this.uInt32),binary_pack(this.smpl.dwMIDIUnityNote,this.uInt32),binary_pack(this.smpl.dwMIDIPitchFraction,this.uInt32),binary_pack(this.smpl.dwSMPTEFormat,this.uInt32),binary_pack(this.smpl.dwSMPTEOffset,this.uInt32),binary_pack(this.smpl.dwNumSampleLoops,this.uInt32),binary_pack(this.smpl.dwSamplerData,this.uInt32),t)),this.enforceByteLen_(e),e}getSmplLoopsBytes_(){let t=[];for(let e=0;e<this.smpl.dwNumSampleLoops;e++)t=t.concat(binary_pack(this.smpl.loops[e].dwName,this.uInt32),binary_pack(this.smpl.loops[e].dwType,this.uInt32),binary_pack(this.smpl.loops[e].dwStart,this.uInt32),binary_pack(this.smpl.loops[e].dwEnd,this.uInt32),binary_pack(this.smpl.loops[e].dwFraction,this.uInt32),binary_pack(this.smpl.loops[e].dwPlayCount,this.uInt32));return t}getFactBytes_(){let e=[];return this.fact.chunkId&&(e=e.concat(packString(this.fact.chunkId),binary_pack(this.fact.chunkSize,this.uInt32),binary_pack(this.fact.dwSampleLength,this.uInt32))),this.enforceByteLen_(e),e}getFmtBytes_(){if(this.fmt.chunkId){var e=[].concat(packString(this.fmt.chunkId),binary_pack(this.fmt.chunkSize,this.uInt32),binary_pack(this.fmt.audioFormat,this.uInt16),binary_pack(this.fmt.numChannels,this.uInt16),binary_pack(this.fmt.sampleRate,this.uInt32),binary_pack(this.fmt.byteRate,this.uInt32),binary_pack(this.fmt.blockAlign,this.uInt16),binary_pack(this.fmt.bitsPerSample,this.uInt16),this.getFmtExtensionBytes_());return this.enforceByteLen_(e),e}throw Error('Could not find the "fmt " chunk')}getFmtExtensionBytes_(){let e=[];return 16<this.fmt.chunkSize&&(e=e.concat(binary_pack(this.fmt.cbSize,this.uInt16))),18<this.fmt.chunkSize&&(e=e.concat(binary_pack(this.fmt.validBitsPerSample,this.uInt16))),20<this.fmt.chunkSize&&(e=e.concat(binary_pack(this.fmt.dwChannelMask,this.uInt32))),24<this.fmt.chunkSize&&(e=e.concat(binary_pack(this.fmt.subformat[0],this.uInt32),binary_pack(this.fmt.subformat[1],this.uInt32),binary_pack(this.fmt.subformat[2],this.uInt32),binary_pack(this.fmt.subformat[3],this.uInt32))),e}getLISTBytes_(){let t=[];for(let e=0;e<this.LIST.length;e++){var i=this.getLISTSubChunksBytes_(this.LIST[e].subChunks,this.LIST[e].format);t=t.concat(packString(this.LIST[e].chunkId),binary_pack(i.length+4,this.uInt32),packString(this.LIST[e].format),i)}return this.enforceByteLen_(t),t}getLISTSubChunksBytes_(i,r){let s=[];for(let e=0,t=i.length;e<t;e++)"INFO"==r?s=s.concat(this.getLISTINFOSubChunksBytes_(i[e])):"adtl"==r&&(s=s.concat(this.getLISTadtlSubChunksBytes_(i[e]))),this.enforceByteLen_(s);return s}getLISTINFOSubChunksBytes_(e){let t=[];var i=writeString(e.value,e.value.length);return t=t.concat(packString(e.chunkId),binary_pack(i.length+1,this.uInt32),i),t.push(0),t}getLISTadtlSubChunksBytes_(e){let t=[];var i;return-1<["labl","note"].indexOf(e.chunkId)?(i=writeString(e.value,e.value.length),t=t.concat(packString(e.chunkId),binary_pack(i.length+4+1,this.uInt32),binary_pack(e.dwName,this.uInt32),i),t.push(0)):"ltxt"==e.chunkId&&(t=t.concat(this.getLtxtChunkBytes_(e))),t}getLtxtChunkBytes_(e){return[].concat(packString(e.chunkId),binary_pack(e.value.length+20,this.uInt32),binary_pack(e.dwName,this.uInt32),binary_pack(e.dwSampleLength,this.uInt32),binary_pack(e.dwPurposeID,this.uInt32),binary_pack(e.dwCountry,this.uInt16),binary_pack(e.dwLanguage,this.uInt16),binary_pack(e.dwDialect,this.uInt16),binary_pack(e.dwCodePage,this.uInt16),writeString(e.value,e.value.length))}get_PMXBytes_(){let e=[];var t;return this._PMX.chunkId&&(t=packString(this._PMX.value),this._PMX.chunkSize=t.length,e=e.concat(packString(this._PMX.chunkId),binary_pack(this._PMX.chunkSize,this.uInt32),t)),this.enforceByteLen_(e),e}getJunkBytes_(){let e=[];return this.junk.chunkId?e.concat(packString(this.junk.chunkId),binary_pack(this.junk.chunkData.length,this.uInt32),this.junk.chunkData):(this.enforceByteLen_(e),e)}enforceByteLen_(e){e.length%2&&e.push(0)}}function interleave(s){let a=[];if(0<s.length)if(s[0].constructor!==Number){a=new Float64Array(s[0].length*s.length);for(let i=0,e=s[0].length,r=0;i<e;i++)for(let e=0,t=s.length;e<t;e++,r++)a[r]=s[e][i]}else a=s;return a}function deInterleave(r,s,t=Float64Array){let a=[];for(let e=0;e<s;e++)a[e]=new t(r.length/s);for(let i=0;i<s;i++)for(let e=i,t=0;e<r.length;e+=s,t++)a[i][t]=r[e];return a}function validateNumChannels(e,t){return!(e<1||65535<e*t/8)}function validateSampleRate(e,t,i){return!(i<1||4294967295<e*(t/8)*i)}class WaveFileCreator extends WaveFileParser{constructor(){super(),this.bitDepth="0",this.dataType={bits:0,be:!1},this.WAV_AUDIO_FORMATS={4:17,8:1,"8a":6,"8m":7,16:1,24:1,32:1,"32f":3,64:3}}fromScratch(e,t,i,r,s){s=s||{},this.clearHeaders(),this.newWavFile_(e,t,i,r,s)}fromBuffer(e,t=!0){super.fromBuffer(e,t),this.bitDepthFromFmt_(),this.updateDataType_()}toBuffer(){return this.validateWavHeader_(),super.toBuffer()}getSamples(e=!1,t=Float64Array){var i=new t(this.data.samples.length/(this.dataType.bits/8));return unpackArrayTo(this.data.samples,this.dataType,i,0,this.data.samples.length),!e&&1<this.fmt.numChannels?deInterleave(i,this.fmt.numChannels,t):i}getSample(e){if((e*=this.dataType.bits/8)+this.dataType.bits/8>this.data.samples.length)throw new Error("Range error");return binary_unpack(this.data.samples.slice(e,e+this.dataType.bits/8),this.dataType)}setSample(e,t){if((e*=this.dataType.bits/8)+this.dataType.bits/8>this.data.samples.length)throw new Error("Range error");packTo(t,this.dataType,this.data.samples,e,!0)}getiXML(){return this.iXML.value}setiXML(e){if("string"!=typeof e)throw new TypeError("iXML value must be a string.");this.iXML.value=e,this.iXML.chunkId="iXML"}get_PMX(){return this._PMX.value}set_PMX(e){if("string"!=typeof e)throw new TypeError("_PMX value must be a string.");this._PMX.value=e,this._PMX.chunkId="_PMX"}newWavFile_(e,t,i,r,s){s.container||(s.container="RIFF"),this.container=s.container,this.bitDepth=i,r=interleave(r),this.updateDataType_();var a=this.dataType.bits/8;this.data.samples=new Uint8Array(r.length*a),packArrayTo(r,this.dataType,this.data.samples,0,!0),this.makeWavHeader_(i,e,t,a,this.data.samples.length,s),this.data.chunkId="data",this.data.chunkSize=this.data.samples.length,this.validateWavHeader_()}makeWavHeader_(e,t,i,r,s,a){"4"==e?this.createADPCMHeader_(e,t,i,r,s,a):"8a"==e||"8m"==e?this.createALawMulawHeader_(e,t,i,r,s,a):-1==Object.keys(this.WAV_AUDIO_FORMATS).indexOf(e)||2<t?this.createExtensibleHeader_(e,t,i,r,s,a):this.createPCMHeader_(e,t,i,r,s,a)}createPCMHeader_(e,t,i,r,s,a){this.container=a.container,this.chunkSize=36+s,this.format="WAVE",this.bitDepth=e,this.fmt={chunkId:"fmt ",chunkSize:16,audioFormat:this.WAV_AUDIO_FORMATS[e]||65534,numChannels:t,sampleRate:i,byteRate:t*r*i,blockAlign:t*r,bitsPerSample:parseInt(e,10),cbSize:0,validBitsPerSample:0,dwChannelMask:0,subformat:[]}}createADPCMHeader_(e,t,i,r,s,a){this.createPCMHeader_(e,t,i,r,s,a),this.chunkSize=40+s,this.fmt.chunkSize=20,this.fmt.byteRate=4055,this.fmt.blockAlign=256,this.fmt.bitsPerSample=4,this.fmt.cbSize=2,this.fmt.validBitsPerSample=505,this.fact={chunkId:"fact",chunkSize:4,dwSampleLength:2*s}}createExtensibleHeader_(e,t,i,r,s,a){this.createPCMHeader_(e,t,i,r,s,a),this.chunkSize=60+s,this.fmt.chunkSize=40,this.fmt.bitsPerSample=1+(parseInt(e,10)-1|7),this.fmt.cbSize=22,this.fmt.validBitsPerSample=parseInt(e,10),this.fmt.dwChannelMask=dwChannelMask_(t),this.fmt.subformat=[1,1048576,2852126848,1905997824]}createALawMulawHeader_(e,t,i,r,s,a){this.createPCMHeader_(e,t,i,r,s,a),this.chunkSize=40+s,this.fmt.chunkSize=20,this.fmt.cbSize=2,this.fmt.validBitsPerSample=8,this.fact={chunkId:"fact",chunkSize:4,dwSampleLength:s}}bitDepthFromFmt_(){3===this.fmt.audioFormat&&32===this.fmt.bitsPerSample?this.bitDepth="32f":6===this.fmt.audioFormat?this.bitDepth="8a":7===this.fmt.audioFormat?this.bitDepth="8m":this.bitDepth=this.fmt.bitsPerSample.toString()}validateBitDepth_(){if(this.WAV_AUDIO_FORMATS[this.bitDepth])return!0;if(8<parseInt(this.bitDepth,10)&&parseInt(this.bitDepth,10)<54)return!0;throw new Error("Invalid bit depth.")}updateDataType_(){this.dataType={bits:1+(parseInt(this.bitDepth,10)-1|7),fp:"32f"==this.bitDepth||"64"==this.bitDepth,signed:"8"!=this.bitDepth,be:"RIFX"==this.container},-1<["4","8a","8m"].indexOf(this.bitDepth)&&(this.dataType.bits=8,this.dataType.signed=!1)}validateWavHeader_(){if(this.validateBitDepth_(),!validateNumChannels(this.fmt.numChannels,this.fmt.bitsPerSample))throw new Error("Invalid number of channels.");if(!validateSampleRate(this.fmt.numChannels,this.fmt.bitsPerSample,this.fmt.sampleRate))throw new Error("Invalid sample rate.")}}function dwChannelMask_(e){let t=0;return 1===e?t=4:2===e?t=3:4===e?t=51:6===e?t=63:8===e&&(t=1599),t}class WaveFileTagEditor extends WaveFileCreator{getTag(e){e=this.getTagIndex_(e);return null!==e.TAG?this.LIST[e.LIST].subChunks[e.TAG].value:null}setTag(e,t){e=fixRIFFTag_(e);var i=this.getTagIndex_(e);null!==i.TAG?(this.LIST[i.LIST].subChunks[i.TAG].chunkSize=t.length+1,this.LIST[i.LIST].subChunks[i.TAG].value=t):null!==i.LIST?this.LIST[i.LIST].subChunks.push({chunkId:e,chunkSize:t.length+1,value:t}):(this.LIST.push({chunkId:"LIST",chunkSize:8+t.length+1,format:"INFO",subChunks:[]}),this.LIST[this.LIST.length-1].subChunks.push({chunkId:e,chunkSize:t.length+1,value:t}))}deleteTag(e){e=this.getTagIndex_(e);return null!==e.TAG&&(this.LIST[e.LIST].subChunks.splice(e.TAG,1),!0)}listTags(){var i=this.getLISTIndex("INFO");let r={};if(null!==i)for(let e=0,t=this.LIST[i].subChunks.length;e<t;e++)r[this.LIST[i].subChunks[e].chunkId]=this.LIST[i].subChunks[e].value;return r}getLISTIndex(i){for(let e=0,t=this.LIST.length;e<t;e++)if(this.LIST[e].format==i)return e;return null}getTagIndex_(r){let s={LIST:null,TAG:null};for(let i=0,e=this.LIST.length;i<e;i++)if("INFO"==this.LIST[i].format){s.LIST=i;for(let e=0,t=this.LIST[i].subChunks.length;e<t;e++)if(this.LIST[i].subChunks[e].chunkId==r){s.TAG=e;break}break}return s}}function fixRIFFTag_(i){if(i.constructor!==String)throw new Error("Invalid tag name.");if(i.length<4)for(let e=0,t=4-i.length;e<t;e++)i+=" ";return i}class WaveFileCueEditor extends WaveFileTagEditor{listCuePoints(){let i=this.getCuePoints_();for(let e=0,t=i.length;e<t;e++)i[e].position=i[e].dwSampleOffset/this.fmt.sampleRate*1e3,i[e].dwSampleLength?(i[e].end=i[e].dwSampleLength/this.fmt.sampleRate*1e3,i[e].end+=i[e].position):i[e].end=null,delete i[e].value;return i}setCuePoint(e){this.cue.chunkId="cue ",e.label||(e.label="");var t=this.getCuePoints_();this.clearLISTadtl_(),this.cue.points=[],e.dwSampleOffset=e.position*this.fmt.sampleRate/1e3,e.dwSampleLength=0,e.end&&(e.dwSampleLength=e.end*this.fmt.sampleRate/1e3-e.dwSampleOffset),0===t.length?this.setCuePoint_(e,1):this.setCuePointInOrder_(t,e),this.cue.dwCuePoints=this.cue.points.length}deleteCuePoint(t){this.cue.chunkId="cue ";var i=this.getCuePoints_();this.clearLISTadtl_();var r=this.cue.points.length;this.cue.points=[];for(let e=0;e<r;e++)e+1!==t&&this.setCuePoint_(i[e],e+1);this.cue.dwCuePoints=this.cue.points.length,this.cue.dwCuePoints?this.cue.chunkId="cue ":(this.cue.chunkId="",this.clearLISTadtl_())}updateLabel(i,r){var s=this.getLISTIndex("adtl");if(null!==s)for(let e=0,t=this.LIST[s].subChunks.length;e<t;e++)this.LIST[s].subChunks[e].dwName==i&&(this.LIST[s].subChunks[e].value=r)}getCuePoints_(){let i=[];for(let t=0;t<this.cue.points.length;t++){var r=this.cue.points[t];let e=this.getDataForCuePoint_(r.dwName);e.label=e.value||"",e.dwPosition=r.dwPosition,e.fccChunk=r.fccChunk,e.dwChunkStart=r.dwChunkStart,e.dwBlockStart=r.dwBlockStart,e.dwSampleOffset=r.dwSampleOffset,i.push(e)}return i}getDataForCuePoint_(e){var t=this.getLISTIndex("adtl"),i={};return null!==t&&this.getCueDataFromLIST_(i,t,e),i}getCueDataFromLIST_(i,r,s){for(let e=0,t=this.LIST[r].subChunks.length;e<t;e++){var a;this.LIST[r].subChunks[e].dwName==s&&(a=this.LIST[r].subChunks[e],i.value=a.value||i.value,i.dwName=a.dwName||0,i.dwSampleLength=a.dwSampleLength||0,i.dwPurposeID=a.dwPurposeID||0,i.dwCountry=a.dwCountry||0,i.dwLanguage=a.dwLanguage||0,i.dwDialect=a.dwDialect||0,i.dwCodePage=a.dwCodePage||0)}}setCuePoint_(e,t){this.cue.points.push({dwName:t,dwPosition:e.dwPosition||0,fccChunk:e.fccChunk||"data",dwChunkStart:e.dwChunkStart||0,dwBlockStart:e.dwBlockStart||0,dwSampleOffset:e.dwSampleOffset}),this.setLabl_(e,t)}setCuePointInOrder_(t,i){let r=!1;for(let e=0;e<t.length;e++)t[e].dwSampleOffset>i.dwSampleOffset&&!r?(this.setCuePoint_(i,e+1),this.setCuePoint_(t[e],e+2),r=!0):this.setCuePoint_(t[e],r?e+2:e+1);r||this.setCuePoint_(i,this.cue.points.length+1)}clearLISTadtl_(){for(let e=0,t=this.LIST.length;e<t;e++)"adtl"==this.LIST[e].format&&this.LIST.splice(e)}setLabl_(e,t){let i=this.getLISTIndex("adtl");null===i&&(this.LIST.push({chunkId:"LIST",chunkSize:4,format:"adtl",subChunks:[]}),i=this.LIST.length-1),this.setLabelText_(i,e,t),e.dwSampleLength&&this.setLtxtChunk_(i,e,t)}setLabelText_(e,t,i){this.LIST[e].subChunks.push({chunkId:"labl",chunkSize:4,dwName:i,value:t.label}),this.LIST[e].chunkSize+=12}setLtxtChunk_(e,t,i){this.LIST[e].subChunks.push({chunkId:"ltxt",chunkSize:20,dwName:i,dwSampleLength:t.dwSampleLength,dwPurposeID:t.dwPurposeID||0,dwCountry:t.dwCountry||0,dwLanguage:t.dwLanguage||0,dwDialect:t.dwDialect||0,dwCodePage:t.dwCodePage||0,value:t.label}),this.LIST[e].chunkSize+=28}}class Interpolator{constructor(e,t,i){this.length_=e,this.scaleFactor_=(e-1)/t,this.interpolate=this.sinc,"point"===i.method?this.interpolate=this.point:"linear"===i.method?this.interpolate=this.linear:"cubic"===i.method&&(this.interpolate=this.cubic),this.tangentFactor_=1-Math.max(0,Math.min(1,i.tension||0)),this.sincFilterSize_=i.sincFilterSize||1,this.kernel_=sincKernel_(i.sincWindow||window_)}point(e,t){return this.getClippedInput_(Math.round(this.scaleFactor_*e),t)}linear(e,t){e=this.scaleFactor_*e;var i=Math.floor(e);return(1-(e-=i))*this.getClippedInput_(i,t)+e*this.getClippedInput_(i+1,t)}cubic(e,t){e=this.scaleFactor_*e;var i=Math.floor(e),r=[this.getTangent_(i,t),this.getTangent_(i+1,t)],s=[this.getClippedInput_(i,t),this.getClippedInput_(i+1,t)],t=(e-=i)*e,i=e*t;return(2*i-3*t+1)*s[0]+(i-2*t+e)*r[0]+(-2*i+3*t)*s[1]+(i-t)*r[1]}sinc(t,i){t=this.scaleFactor_*t;var e=Math.floor(t),r=e-this.sincFilterSize_+1,s=e+this.sincFilterSize_;let a=0;for(let e=r;e<=s;e++)a+=this.kernel_(t-e)*this.getClippedInput_(e,i);return a}getTangent_(e,t){return this.tangentFactor_*(this.getClippedInput_(e+1,t)-this.getClippedInput_(e-1,t))/2}getClippedInput_(e,t){return 0<=e&&e<this.length_?t[e]:0}}function window_(e){return Math.exp(-e/2*e/2)}function sincKernel_(t){return function(e){return sinc_(e)*t(e)}}function sinc_(e){return 0===e?1:Math.sin(Math.PI*e)/(Math.PI*e)}class FIRLPF{constructor(t,e,i){var r=2*Math.PI*i/e;let s=0;this.filters=[];for(let e=0;e<=t;e++)e-t/2==0?this.filters[e]=r:(this.filters[e]=Math.sin(r*(e-t/2))/(e-t/2),this.filters[e]*=.54-.46*Math.cos(2*Math.PI*e/t)),s+=this.filters[e];for(let e=0;e<=t;e++)this.filters[e]/=s;this.z=this.initZ_()}filter(e){this.z.buf[this.z.pointer]=e;let i=0;for(let e=0,t=this.z.buf.length;e<t;e++)i+=this.filters[e]*this.z.buf[(this.z.pointer+e)%this.z.buf.length];return this.z.pointer=(this.z.pointer+1)%this.z.buf.length,i}reset(){this.z=this.initZ_()}initZ_(){let t=[];for(let e=0;e<this.filters.length-1;e++)t.push(0);return{buf:t,pointer:0}}}class ButterworthLPF{constructor(t,i,r){let s=[];for(let e=0;e<t;e++)s.push(this.getCoeffs_({Fs:i,Fc:r,Q:.5/Math.sin(Math.PI/(2*t)*(e+.5))}));this.stages=[];for(let e=0;e<s.length;e++)this.stages[e]={b0:s[e].b[0],b1:s[e].b[1],b2:s[e].b[2],a1:s[e].a[0],a2:s[e].a[1],k:s[e].k,z:[0,0]}}filter(e){let i=e;for(let e=0,t=this.stages.length;e<t;e++)i=this.runStage_(e,i);return i}getCoeffs_(e){let t={a:[],b:[]};e=this.preCalc_(e,t);return t.k=1,t.b.push((1-e.cw)/(2*e.a0)),t.b.push(2*t.b[0]),t.b.push(t.b[0]),t}preCalc_(e,t){let i={};var r=2*Math.PI*e.Fc/e.Fs;return i.alpha=Math.sin(r)/(2*e.Q),i.cw=Math.cos(r),i.a0=1+i.alpha,t.a0=i.a0,t.a.push(-2*i.cw/i.a0),t.k=1,t.a.push((1-i.alpha)/i.a0),i}runStage_(e,t){var i=t*this.stages[e].k-this.stages[e].a1*this.stages[e].z[0]-this.stages[e].a2*this.stages[e].z[1],t=this.stages[e].b0*i+this.stages[e].b1*this.stages[e].z[0]+this.stages[e].b2*this.stages[e].z[1];return this.stages[e].z[1]=this.stages[e].z[0],this.stages[e].z[0]=i,t}reset(){for(let e=0;e<this.stages.length;e++)this.stages[e].z=[0,0]}}const DEFAULT_LPF_USE={point:!1,linear:!1,cubic:!0,sinc:!0},DEFAULT_LPF_ORDER={IIR:16,FIR:71},DEFAULT_LPF={IIR:ButterworthLPF,FIR:FIRLPF};function resample(e,t,i,r=null){r=r||{};var s=new Float64Array(e.length*((i-t)/t+1));r.method=r.method||"cubic";var a=new Interpolator(e.length,s.length,{method:r.method,tension:r.tension||0,sincFilterSize:r.sincFilterSize||6,sincWindow:r.sincWindow||void 0,clip:r.clip||"mirror"});if(void 0===r.LPF&&(r.LPF=DEFAULT_LPF_USE[r.method]),r.LPF){r.LPFType=r.LPFType||"IIR";const n=DEFAULT_LPF[r.LPFType];t<i?upsample_(e,s,a,new n(r.LPForder||DEFAULT_LPF_ORDER[r.LPFType],i,t/2)):downsample_(e,s,a,new n(r.LPForder||DEFAULT_LPF_ORDER[r.LPFType],t,i/2))}else resample_(e,s,a);return s}function resample_(i,r,s){for(let e=0,t=r.length;e<t;e++)r[e]=s.interpolate(e,i)}function upsample_(i,r,s,a){for(let e=0,t=r.length;e<t;e++)r[e]=a.filter(s.interpolate(e,i));a.reset();for(let e=r.length-1;0<=e;e--)r[e]=a.filter(r[e])}function downsample_(i,e,t,r){for(let e=0,t=i.length;e<t;e++)i[e]=r.filter(i[e]);r.reset();for(let e=i.length-1;0<=e;e--)i[e]=r.filter(i[e]);resample_(i,e,t)}class WaveFileConverter extends WaveFileCueEditor{toRIFF(){var e=new Float64Array(outputSize_(this.data.samples.length,this.dataType.bits/8));unpackArrayTo(this.data.samples,this.dataType,e,0,this.data.samples.length),this.fromExisting_(this.fmt.numChannels,this.fmt.sampleRate,this.bitDepth,e,{container:"RIFF"})}toRIFX(){var e=new Float64Array(outputSize_(this.data.samples.length,this.dataType.bits/8));unpackArrayTo(this.data.samples,this.dataType,e,0,this.data.samples.length),this.fromExisting_(this.fmt.numChannels,this.fmt.sampleRate,this.bitDepth,e,{container:"RIFX"})}toIMAADPCM(){if(8e3!==this.fmt.sampleRate)throw new Error("Only 8000 Hz files can be compressed as IMA-ADPCM.");if(1!==this.fmt.numChannels)throw new Error("Only mono files can be compressed as IMA-ADPCM.");this.assure16Bit_();var e=new Int16Array(outputSize_(this.data.samples.length,2));unpackArrayTo(this.data.samples,this.dataType,e,0,this.data.samples.length),this.fromExisting_(this.fmt.numChannels,this.fmt.sampleRate,"4",imaadpcm_encode(e),{container:this.correctContainer_()})}fromIMAADPCM(e="16"){let s;if(1<this.fmt.numChannels){if(2<this.fmt.numChannels)throw new Error("Only 1 or 2 channels are supported");var a=this.data.samples.length/2;let t=new Uint8Array(a),i=new Uint8Array(a),r=0;for(let e=0;e<a;e++)e&&e%4==0&&(r+=4),t[e]=this.data.samples[r+e],i[e]=this.data.samples[r+e+4];s=[imaadpcm_decode(t,this.fmt.blockAlign/2),imaadpcm_decode(i,this.fmt.blockAlign/2)]}else s=imaadpcm_decode(this.data.samples,this.fmt.blockAlign);this.fromExisting_(this.fmt.numChannels,this.fmt.sampleRate,"16",s,{container:this.correctContainer_()}),"16"!=e&&this.toBitDepth(e)}toALaw(){this.assure16Bit_();var e=new Int16Array(outputSize_(this.data.samples.length,2));unpackArrayTo(this.data.samples,this.dataType,e,0,this.data.samples.length),this.fromExisting_(this.fmt.numChannels,this.fmt.sampleRate,"8a",alaw_encode(e),{container:this.correctContainer_()})}fromALaw(e="16"){this.fromExisting_(this.fmt.numChannels,this.fmt.sampleRate,"16",alaw_decode(this.data.samples),{container:this.correctContainer_()}),"16"!=e&&this.toBitDepth(e)}toMuLaw(){this.assure16Bit_();var e=new Int16Array(outputSize_(this.data.samples.length,2));unpackArrayTo(this.data.samples,this.dataType,e,0,this.data.samples.length),this.fromExisting_(this.fmt.numChannels,this.fmt.sampleRate,"8m",mulaw_encode(e),{container:this.correctContainer_()})}fromMuLaw(e="16"){this.fromExisting_(this.fmt.numChannels,this.fmt.sampleRate,"16",mulaw_decode(this.data.samples),{container:this.correctContainer_()}),"16"!=e&&this.toBitDepth(e)}toBitDepth(e,t=!0){let i=e,r=this.bitDepth;t||("32f"!=e&&(i=this.dataType.bits.toString()),r=""+this.dataType.bits),this.assureUncompressed_();var s=this.getSamples(!0),t=new Float64Array(s.length);changeBitDepth(s,r,t,i),this.fromExisting_(this.fmt.numChannels,this.fmt.sampleRate,e,t,{container:this.correctContainer_()})}toSampleRate(t,i){this.validateResample_(t);var r=this.getSamples();let s=[];if(r.constructor===Float64Array)s=resample(r,this.fmt.sampleRate,t,i);else for(let e=0;e<r.length;e++)s.push(resample(r[e],this.fmt.sampleRate,t,i));this.fromExisting_(this.fmt.numChannels,t,this.bitDepth,s,{container:this.correctContainer_()})}validateResample_(e){if(!validateSampleRate(this.fmt.numChannels,this.fmt.bitsPerSample,e))throw new Error("Invalid sample rate.");if(-1<["4","8a","8m"].indexOf(this.bitDepth))throw new Error("wavefile can't change the sample rate of compressed files.")}assure16Bit_(){this.assureUncompressed_(),"16"!=this.bitDepth&&this.toBitDepth("16")}assureUncompressed_(){"8a"==this.bitDepth?this.fromALaw():"8m"==this.bitDepth?this.fromMuLaw():"4"==this.bitDepth&&this.fromIMAADPCM()}correctContainer_(){return"RF64"==this.container?"RIFF":this.container}fromExisting_(e,t,i,r,s){var a=new WaveFileCueEditor;Object.assign(this.fmt,a.fmt),Object.assign(this.fact,a.fact),Object.assign(this.ds64,a.ds64),Object.assign(this.data,a.data),this.newWavFile_(e,t,i,r,s)}}function outputSize_(e,t){let i=e/t;return i%2&&i++,i}class WaveFile extends WaveFileConverter{constructor(e){super(),e&&this.fromBuffer(e)}fromBase64(e){this.fromBuffer(decode(e))}toBase64(){return encode(this.toBuffer())}toDataURI(){return"data:audio/wav;base64,"+this.toBase64()}fromDataURI(e){this.fromBase64(e.replace("data:audio/wav;base64,",""))}}class WavFile{constructor(e){e instanceof Uint8Array?this.fromRawData(e):e instanceof VirtualFile&&this.fromVirtualFile(e)}fromRawData(e){return this.rawData=e,this}fromVirtualFile(e){e=e.stream;return this.rawData=new Uint8Array(e.buffer,e.byteOffset,e.byteLength),this}getRawData(){return this.rawData}getData(){if(!this.decodedData){if(!this.rawData)throw new Error("No data loaded");this.decodedData=this.decodeData(this.rawData),this.rawData=void 0}return this.decodedData}setData(e){this.rawData=void 0,this.decodedData=e}decodeData(e){let t=new WaveFile(e);return"4"===t.bitDepth&&t.fromIMAADPCM(),t.toBuffer()}isRawImaAdpcm(){return this.rawData&&"4"===new WaveFile(this.rawData).bitDepth}}class LazyAsyncResourceCollection{constructor(e,t=!0){this.resourceFactory=e,this.cache=t,this.resources=new Map}setDir(e){this.rfsDir=e}set(e,t){this.resources.set(e,t)}async has(e){return!!this.resources.has(e)||(await this.rfsDir?.containsEntry(e)??!1)}async get(e){let t;return t=this.resources.get(e),!t&&await this.rfsDir?.containsEntry(e)&&(t=await this.resourceFactory(await this.rfsDir.getRawFile(e)),this.cache&&this.resources.set(e,t)),t}clear(){this.resources.clear()}}class Mp3File{constructor(e){this.file=e}asFile(){return new File([this.file],this.file.name,{type:"audio/mp3"})}}const mixDatabase=(new Map).set("cameo.mix",["adogicon.shp","adoguico.shp","aengicon.shp","aenguico.shp","agapgen.shp","agisicon.shp","ahrvicon.shp","ahrvuico.shp","aparicon.shp","apchicon.shp","apcicon.shp","artyicon.shp","asaticon.shp","ayaricon.shp","batricon.shp","beagicon.shp","bggyicon.shp","bolticon.shp","brrkicon.shp","carricon.shp","ccomicon.shp","ccomuico.shp","chemicon.shp","chroicon.shp","clckicon.shp","clegicon.shp","cleguico.shp","clonicon.shp","cnsticon.shp","crryicon.shp","csphicon.shp","darken.shp","desoicon.shp","desouico.shp","desticon.shp","detnicon.shp","dlphicon.shp","dlphuico.shp","dogicon.shp","doguico.shp","dredicon.shp","dronicon.shp","e1icon.shp","e1uico.shp","e2icon.shp","e2uico.shp","e4icon.shp","empicon.shp","engnicon.shp","facticon.shp","falcicon.shp","fixicon.shp","flakicon.shp","flkticon.shp","flktuico.shp","forticon.shp","fsdicon.shp","fspicon.shp","fstdicon.shp","fvicon.shp","fvuico.shp","gapicon.shp","gat2icon.shp","gateicon.shp","gbayicon.shp","gcanicon.shp","giicon.shp","giuico.shp","gorep.shp","gtnkicon.shp","gtnkuico.shp","gwepicon.shp","handicon.shp","harvicon.shp","harvuico.shp","heliicon.shp","hindicon.shp","hmecicon.shp","hovricon.shp","htkicon.shp","htkuico.shp","htnkicon.shp","htnkuico.shp","ioncicon.shp","ircricon.shp","ironicon.shp","ivanicon.shp","ivanuico.shp","ivncicon.shp","ivncuico.shp","jjeticon.shp","jjetuico.shp","landicon.shp","lasricon.shp","liteicon.shp","lpsticon.shp","mcvicon.shp","mcvuico.shp","metricon.shp","mltiicon.shp","mmchicon.shp","msslicon.shp","mtnkicon.shp","mtnkuico.shp","mutcicon.shp","nga2icon.shp","ngaticon.shp","nhpdicon.shp","npsiicon.shp","npwricon.shp","nradicon.shp","nrcticon.shp","nreficon.shp","ntchicon.shp","nukeicon.shp","nwalicon.shp","nwepicon.shp","obliicon.shp","obmbicon.shp","orcaicon.shp","otrnicon.shp","paraicon.shp","pillicon.shp","plticon.shp","plugicon.shp","podsicon.shp","powricon.shp","prisicon.shp","proicon.shp","psicicon.shp","psicuico.shp","psisicon.shp","psiticon.shp","psituico.shp","rad1icon.shp","rad2icon.shp","rad3icon.shp","radricon.shp","rboticon.shp","reficon.shp","rfixicon.shp","rtnkicon.shp","rtnkuico.shp","samicon.shp","sapcicon.shp","sapicon.shp","sbagicon.shp","sealicon.shp","sealuico.shp","seekicon.shp","shadicon.shp","shaduico.shp","shkicon.shp","shkuico.shp","smchicon.shp","smcvicon.shp","smcvuico.shp","snipicon.shp","snipuico.shp","soniicon.shp","spoticon.shp","spyicon.shp","spyuico.shp","sqdicon.shp","sreficon.shp","srefuico.shp","stnkicon.shp","subicon.shp","subticon.shp","tanyicon.shp","tanyuico.shp","techicon.shp","tempicon.shp","teslaicon.shp","tickicon.shp","tnkdicon.shp","tnkduico.shp","towricon.shp","trkaicon.shp","trsticon.shp","trstuico.shp","tslaicon.shp","ttnkicon.shp","ttnkuico.shp","turbicon.shp","twr1icon.shp","twr2icon.shp","twr3icon.shp","v3icon.shp","v3uico.shp","wallicon.shp","weapicon.shp","weaticon.shp","weedicon.shp","wethicon.shp","xxicon.shp","yardicon.shp","yuriicon.shp","yuriuico.shp","yurpicon.shp","yurpuico.shp","zepicon.shp","zepuico.shp"]).set("theme.mix",["200meter.wav","blowitup.wav","burn.wav","destroy.wav","eaglehun.wav","fortific.wav","grinder.wav","hm2.wav","indeep.wav","industro.wav","jank.wav","motorize.wav","power.wav","ra2-opt.wav","ra2-sco.wav","tension.wav"]).set("thememd.mix",["brainfre.wav","bully.wav","deceiver.wav","defend.wav","drok.wav","optionx.wav","phatatta.wav","scorex.wav","tactics.wav","trancelv.wav"]);let sidecResources=["addon.shp","bkgdlg.shp","bkgdmd.shp","bkgdsm.shp","bttnbkgd.shp","button00.shp","button01.shp","button02.shp","button03.shp","button04.shp","button05.shp","button06.shp","button07.shp","button08.shp","button09.shp","button10.shp","button11.shp","credits.shp","diplobtn.shp","gclock2.shp","key.ini","lendcap.shp","lspacer.shp","optbtn.shp","pbeacon.shp","power.shp","powerp.shp","pwrlvl.shp","radar.shp","radar01.shp","radar02.shp","r-dn.shp","rdrbeacn.shp","rendcap.shp","repair.shp","r-up.shp","sell.shp","side1.shp","side2.shp","side2b.shp","side3.shp","sidebar.pal","sidebttn.shp","tab00.shp","tab01.shp","tab02.shp","tab03.shp","tabs.shp","top.shp","uibkgd.pal","wayp.shp"];mixDatabase.set("sidec01.mix",sidecResources).set("sidec02.mix",sidecResources);let sideccdResources=["reportbug.shp"];mixDatabase.set("sidec01cd.mix",sideccdResources).set("sidec02cd.mix",sideccdResources),function(e){e[e.Archive=0]="Archive",e[e.Cdn=1]="Cdn",e[e.Local=2]="Local"}(GameResSource=GameResSource||{});class MpDialogSettings{readIni(e){return this.minMoney=e.getNumber("MinMoney"),this.money=e.getNumber("Money"),this.maxMoney=e.getNumber("MaxMoney"),this.moneyIncrement=e.getNumber("MoneyIncrement"),this.minUnitCount=e.getNumber("MinUnitCount"),this.unitCount=e.getNumber("UnitCount"),this.maxUnitCount=e.getNumber("MaxUnitCount"),this.crates=e.getBool("Crates"),this.gameSpeed=e.getNumber("GameSpeed"),this.mcvRedeploys=e.getBool("MCVRedeploys"),this.shortGame=e.getBool("ShortGame"),this.superWeapons=e.getBool("SuperWeapons"),this.techLevel=e.getNumber("TechLevel"),this.alliesAllowed=e.getBool("AlliesAllowed",!0),this.allyChangeAllowed=e.getBool("AllyChangeAllowed",!0),this.mustAlly=e.getBool("MustAlly"),this.bridgeDestruction=e.getBool("BridgeDestruction",!0),this.multiEngineer=e.getBool("MultiEngineer"),this}}!function(e){e[e.Battle=0]="Battle",e[e.ManBattle=1]="ManBattle",e[e.FreeForAll=2]="FreeForAll",e[e.Unholy=3]="Unholy",e[e.Cooperative=4]="Cooperative"}(GameModeType=GameModeType||{});class GameModes{constructor(e,t){this.modeIniLoader=t,this.entries=new Map,this.loadIni(e)}loadIni(e){e.getOrderedSections().forEach(r=>{let s=GameModeType[r.name]??GameModeType.Battle;[...r.entries.keys()].forEach(e=>{let t=r.getArray(e);if(t.length<5)throw new Error(`Invalid format for mp mode entry "${e}".`);var i=Number(e),e=t[2].toLowerCase(),e={id:i,type:s,label:t[0],description:t[1],rulesOverride:e,mapFilter:t[3],randomMapsAllowed:t[4],aiAllowed:i<3,mpDialogSettings:(new MpDialogSettings).readIni(this.modeIniLoader(e).getOrCreateSection("MultiplayerDialogSettings"))};this.entries.set(i,e)})})}getById(e){if(!this.entries.has(e))throw new Error("No game mode found with id "+e);return this.entries.get(e)}hasId(e){return this.entries.has(e)}getAll(){return[...this.entries.values()]}}class MapManifest{fromIni(t,e){return this.fileName=t.getString("File")||t.name.toLowerCase()+".map",this.uiName=t.getString("Description"),this.maxSlots=t.getNumber("MaxPlayers"),this.official=!0,this.gameModes=e.filter(e=>t.getArray("GameMode").includes(e.mapFilter)),this}getFullMapTitle(e){return this.addTitleSlotsSuffix(e.get(this.uiName),this.maxSlots)}addTitleSlotsSuffix(e,t){return e.match(/(\(|()\s*\d(-\d)?\s*(\)|))\s*$/)||(e+=` (2${2<t?"-"+t:""})`),e}fromMapFile(e,t){var i=e.readAsString();let r=e.filename;const s=new IniFile(this.extractIniSection("Basic",i)).getSection("Basic");if(!s)throw new Error(`Map "${r}" is missing the [Basic] section`);this.fileName=r,this.uiName="NOSTR:"+(s.getString("Name")||r.replace(/\.[^.]+$/,""));i=this.extractIniSection("Waypoints",i);let a=i?new IniFile(i).getSection("Waypoints"):void 0;this.maxSlots=[...a?.entries.keys()??[]].filter(e=>Number(e)<8).length,this.official=s.getBool("Official");let n=s.getArray("GameMode",void 0,["standard"]);return this.gameModes=t.filter(e=>n.includes(e.mapFilter)),this}extractIniSection(t,i){t=i.indexOf(`[${t}]`);if(-1!==t){let e=t+1;for(;e<i.length&&("["!==i[e]||"\n"!==i[e-1]);e++);return i.slice(t,e)}}}class MapList{constructor(e){this.gameModes=e,this.manifests=[]}addFromIni(i){let e=i.getSection("MultiMaps");if(!e)throw new Error("Invalid map list. Missing [MultiMaps] section.");return this.manifests=this.manifests.concat([...e.entries.values()].map(e=>{var t=i.getSection(e);if(!t)throw new Error(`Invalid map list. Missing [${e}] section.`);return(new MapManifest).fromIni(t,this.gameModes.getAll())})),this.dedupeEntries(),this}add(e){this.manifests.push(e)}addFromMapFile(e){this.add((new MapManifest).fromMapFile(e,this.gameModes.getAll()))}getAll(){return this.manifests}getByName(t){return this.manifests.find(e=>e.fileName.toLowerCase()===t.toLowerCase())}sortByName(){this.manifests.sort((e,t)=>e.fileName.localeCompare(t.fileName))}clone(){let e=new MapList(this.gameModes);return e.manifests=[...this.manifests],e}mergeWith(e){return this.manifests.push(...e.manifests),this.dedupeEntries(),this}dedupeEntries(){this.manifests=[...new Map(this.manifests.map(e=>[e.fileName.toLowerCase(),e])).values()]}}class Section_Section{getMatrix(e){return this.matrices[e]}}var MixinRulesType,_a,ObjectType,HvaFile_THREE=__webpack_require__(70);class HvaFile{constructor(e){e instanceof VirtualFile&&this.fromVirtualFile(e)}fromVirtualFile(e){this.filename=e.filename;let i=e.stream;this.sections=[],i.readCString(16);var r=i.readInt32(),s=i.readInt32();for(let e=0;e<s;++e){let e=new Section_Section;e.name=i.readCString(16),e.matrices=new Array(r),this.sections.push(e)}for(let t=0;t<r;++t)for(let e=0;e<s;++e)this.sections[e].matrices[t]=this.readMatrix(i)}readMatrix(t){let i=[];for(let e=0;e<3;++e)i.push(t.readFloat32(),t.readFloat32(),t.readFloat32(),t.readFloat32());return i.push(0,0,0,1),(new HvaFile_THREE.Matrix4).fromArray(i).transpose()}}!function(e){e[e.NoDogEngiKills=0]="NoDogEngiKills"}(MixinRulesType=MixinRulesType||{});class Engine{static getVersion(){return version.split(".").slice(0,2).join(".")}static getModHash(){if(!this.modHash)throw new Error("Rules must be loaded first");return this.modHash}static getActiveMod(){return this.activeMod}static setActiveMod(e){this.activeMod=e}static initGameResSource(e){this.gameResSource=e}static async initRfs(e){let t=this.rfs=new RealFileSystem;return t.addRootDirectoryHandle(e),t}static async initVfs(e,t){return this.vfs=new VirtualFileSystem(e,t),_a.iniFiles.setVfs(this.vfs),_a.palettes.setVfs(this.vfs),_a.images.setVfs(this.vfs),_a.voxels.setVfs(this.vfs),_a.voxelAnims.setVfs(this.vfs),_a.tileData.setVfs(this.vfs),_a.sounds.setVfs(this.vfs),_a.themes.setDir(await this.rfs?.findDirectory(_a.rfsSettings.musicDir)),_a.taunts.setDir(await this.rfs?.findDirectory(_a.rfsSettings.tauntsDir)),this.vfs}static supportsTheater(t){var e=this.getActiveEngine();return this.theaterSettings.get(e)?.some(e=>e.type===t)||!1}static getTheaterSettings(e,t){if(!this.theaterSettings.has(e))throw new Error('Unknown engineType "'+e);e=this.theaterSettings.get(e).find(e=>e.type===t);if(!e)throw new Error(`Unsupported theater "${TheaterType[t]}"`);return e}static async loadTheater(e){if(!_a.rules||!_a.art)throw new Error("Rules and art should be loaded first");if(void 0===_a.gameResSource)throw new Error("No gameResSource is set");var t=_a.getActiveEngine();let i;var r,s=_a.getTheaterSettings(t,e);if(_a.gameResSource!==GameResSource.Cdn)for(var a of s.mixes)await _a.vfs.addMixFile(a);return _a.theaters.has(e)?i=_a.theaters.get(e):(r=_a.getTheaterIni(t,e),t=_a.getTileData(),i=Theater.factory(e,r,s,t,_a.palettes),_a.theaters.set(e,i)),_a.activeTheater=i,i}static unloadTheater(e){if(_a.vfs){var t,i=_a.getActiveEngine();for(t of _a.getTheaterSettings(i,e).mixes)_a.vfs.removeArchive(t)}}static unloadSideMixData(){for(var e of["sidec01.mix","sidec01cd.mix"]){var t,i=mixDatabase.get(e);if(!i)return void console.warn(`Mix "${e}" not found in mix database`);for(t of i)("pal"===t.split(".").pop()?_a.palettes:_a.images).clear(t)}}static getTheaterIni(e,t){t=_a.getTheaterSettings(e,t).theaterIni;return _a.getIni(t)}static loadRules(){var e=this.getFileNameVariant("rules.ini"),t=this.getFileNameVariant("art.ini"),i=this.getFileNameVariant("ai.ini");let r=this.iniFiles.get(e),s=this.iniFiles.get(t);var a=this.iniFiles.get(i);if(!r)throw new Error(`Rules "${e}" not found`);if(!s)throw new Error(`Art "${t}" not found`);if(!a)throw new Error(`AI "${i}" not found`);t=this.iniFiles.get(_a.customRulesFileName),i=this.iniFiles.get(_a.customArtFileName);if(!t)throw new Error(`Rules "${_a.customRulesFileName}" not found`);if(!i)throw new Error(`Art "${_a.customArtFileName}" not found`);_a.art=s.clone().mergeWith(i),_a.rules=_a.patchAudioVisualRules(r.clone().mergeWith(t)),_a.ai=a,_a.modHash=_a.computeModHash()}static patchAudioVisualRules(i){if(this.activeEngine===EngineType.YurisRevenge){let t=i.getSection("General");if(t){let e=i.getSection("AudioVisual");var r;for(r of["DamageFireTypes","OreTwinkle","BarrelExplode","BarrelDebris","BarrelParticle","NukeTakeOff","Wake","DropPod","DeadBodies","MetallicDebris","BridgeExplosions","IonBlast","IonBeam","WeatherConClouds","WeatherConBolts","WeatherConBoltExplosion","DominatorWarhead","DominatorDamage","DominatorCaptureRange","DominatorFirstAnim","DominatorSecondAnim","DominatorFireAtPercentage","ChronoPlacement","ChronoBeam","ChronoBlast","ChronoBlastDest","WarpIn","WarpOut","WarpAway","IronCurtainInvokeAnim","ForceShieldInvokeAnim","WeaponNullifyAnim","ChronoSparkle1","InfantryExplode","FlamingInfantry","InfantryHeadPop","InfantryNuked","InfantryVirus","InfantryBrute","InfantryMutate","Behind","MoveFlash","Parachute","BombParachute","DropZoneAnim","EMPulseSparkles"])e?.set(r,t.getString(r))}}return i}static computeModHash(){if(!this.vfs)throw new Error("VFS not initialized");let e=[this.customRulesFileName,this.customArtFileName,this.customMpModesFileName,this.shroudFileName,this.getFileNameVariant("rules.ini"),this.getFileNameVariant("art.ini"),this.getFileNameVariant("ai.ini"),..._a.mixinRulesFileNames.values()];var t,i,r,s=this.theaterSettings.get(this.getActiveEngine());if(!s)throw new Error('Unsupported engineType "'+this.getActiveEngine());for(t of s)e.push(t.theaterIni);let a=this.getMpModes();for(i of a.getAll())e.push(i.rulesOverride);let n=new Crc32;for(r of e){if(!this.vfs.fileExists(r))throw new Error(`File ${r} not found`);var o=this.vfs.openFile(r).stream;n.append(new Uint8Array(o.buffer,o.byteOffset,o.byteLength))}return n.append(binaryStringToUint8Array(this.getVersion())),n.get()}static getRules(){if(!_a.rules)throw new Error("Rules must be loaded first");return _a.rules}static getArt(){if(!_a.art)throw new Error("Art must be loaded first");return _a.art}static getAi(){if(!_a.ai)throw new Error("AI must be loaded first");return _a.ai}static getFileNameVariant(e){var t=this.getActiveEngine();let i;if(t===EngineType.YurisRevenge)i="md";else{if(t!==EngineType.RedAlert2)throw new Error("Unsupported engine type "+EngineType[t]);i=""}return i?e.replace(/\.([^.]+)$/,i+".$1"):e}static getMpModes(){return new GameModes(this.getIni(this.customMpModesFileName),e=>this.getIni(e))}static getSoundIni(){var e=this.getIni("soundcd.ini");const t=this.getIni(this.getFileNameVariant("sound.ini"));return t.clone().mergeWith(e)}static getUiIni(){var e=this.getFileNameVariant("ui.ini");return this.getIni(e)}static getIni(e){if(!this.iniFiles.has(e))throw new Error(`INI file ${e} not found.`);return this.iniFiles.get(e)}static async loadMapList(){if(!this.vfs)throw new Error("File system not initialized");var e,i,r,t=this.getMpModes();let s=new MapList(t);s.addFromIni(this.getIni(this.getFileNameVariant("missions.pkt")));for(e of this.vfs.listArchives()){var a=e.toLowerCase().replace(/\.[^.]+$/,"")+".pkt";this.vfs.fileExists(a)&&s.addFromIni(new IniFile(this.vfs.openFile(a)))}let n=new MapList(t),o=this.supportedMapTypes.get(this.getActiveEngine());if(!o)throw new Error(`No map types defined for engine type "${_a.getActiveEngine()}"`);if(this.rfs)for await(var l of this.rfs.getEntries()){let t=l.toLowerCase();try{t.endsWith(".pkt")?(i=new IniFile(await this.rfs.openFile(l,!0)),s.addFromIni(i)):o.some(e=>t.endsWith("."+e))&&(r=await this.rfs.openFile(l,!0),n.addFromMapFile(r))}catch(e){console.warn(`Couldn't read file "${l}"`,e)}}return n.sortByName(),s.mergeWith(n),this.mapList=s,s}static getTileData(){return _a.tileData}static getImages(){return _a.images}static getVoxels(){return _a.voxels}static getVoxelAnims(){return _a.voxelAnims}static getPalettes(){return _a.palettes}static getSounds(){return _a.sounds}static getThemes(){return _a.themes}static getTaunts(){return _a.taunts}static getActiveEngine(){if(!this.activeEngine)throw new Error("Engine type not initialized");return this.activeEngine}static setActiveEngine(e){this.activeEngine=e}static getLastTheaterType(){return _a.activeTheater?.type}static getCacheDir(){try{return this.getOrCreateDir(this.rfsSettings.cacheDir,!0)}catch(e){return void console.error("Couldn't get cache directory",[e])}}static async getReplayDir(){var i=this.getActiveMod();if(i){let e=await this.getModDir(),t=await e?.getDirectory(i);return t?.getOrCreateDirectory(_a.rfsSettings.replayDir)}return this.getOrCreateDir(this.rfsSettings.replayDir)}static getModDir(){return this.getOrCreateDir(_a.rfsSettings.modDir)}static getMapDir(){return this.getOrCreateDir(_a.rfsSettings.mapDir)}static async getOrCreateDir(e,t=!1){let i=this.rfs?.getRootDirectory();if(i)return await i.getOrCreateDirectory(e,t)}static getMapList(){return this.mapList}static destroy(){this.activeEngine=void 0,this.activeTheater=void 0,this.activeMod=void 0,this.modHash=void 0,this.mapList=void 0,this.rfs=void 0,this.vfs=void 0,this.art=void 0,this.iniFiles.clear(),this.images.clear(),this.palettes.clear(),this.rules=void 0,this.ai=void 0,this.theaters.clear(),this.tileData.clear(),this.voxels.clear(),this.voxelAnims.clear()}}_a=Engine,Engine.UI_ANIM_SPEED=2,Engine.rfsSettings={menuVideoFileName:"ra2ts_l.webm",splashImgFileName:"glsl.png",mapDir:"maps",modDir:"mods",musicDir:"music",tauntsDir:"Taunts",cacheDir:"cache",replayDir:"replays"},Engine.supportedMapTypes=new Map([[EngineType.RedAlert2,["mpr","map"]],[EngineType.YurisRevenge,["mpr","map","yrm"]]]),Engine.images=new LazyResourceCollection(e=>new ShpFile(e)),Engine.voxels=new LazyResourceCollection(e=>new VxlFile(e)),Engine.voxelAnims=new LazyResourceCollection(e=>new HvaFile(e)),Engine.sounds=new LazyResourceCollection(e=>new WavFile(e)),Engine.themes=new LazyAsyncResourceCollection(e=>new Mp3File(e),!1),Engine.taunts=new LazyAsyncResourceCollection(async e=>new WavFile(new Uint8Array(await e.arrayBuffer()))),Engine.iniFiles=new LazyResourceCollection(e=>new IniFile(e)),Engine.tileData=new LazyResourceCollection(e=>new TmpFile(e)),Engine.palettes=new LazyResourceCollection(e=>new Palette(e)),Engine.theaters=new Map,Engine.theaterSettings=(new Map).set(EngineType.RedAlert2,[{type:TheaterType.Temperate,theaterIni:"temperat.ini",mixes:["isotemp.mix","temperat.mix","tem.mix"],extension:".tem",newTheaterChar:"T",isoPaletteName:"isotem.pal",unitPaletteName:"unittem.pal",overlayPaletteName:"temperat.pal",libPaletteName:"libtem.pal"},{type:TheaterType.Snow,theaterIni:"snow.ini",mixes:["isosnow.mix","snow.mix","sno.mix"],extension:".sno",newTheaterChar:"A",isoPaletteName:"isosno.pal",unitPaletteName:"unitsno.pal",overlayPaletteName:"snow.pal",libPaletteName:"libsno.pal"},{type:TheaterType.Urban,theaterIni:"urban.ini",mixes:["isourb.mix","urb.mix","urban.mix"],extension:".urb",newTheaterChar:"U",isoPaletteName:"isourb.pal",unitPaletteName:"uniturb.pal",overlayPaletteName:"urban.pal",libPaletteName:"liburb.pal"}]).set(EngineType.YurisRevenge,[{type:TheaterType.Temperate,theaterIni:"temperatmd.ini",mixes:["isotemp.mix","isotemmd.mix","temperat.mix","tem.mix"],extension:".tem",newTheaterChar:"T",isoPaletteName:"isotem.pal",unitPaletteName:"unittem.pal",overlayPaletteName:"temperat.pal",libPaletteName:"libtem.pal"},{type:TheaterType.Snow,theaterIni:"snowmd.ini",mixes:["isosnomd.mix","snowmd.mix","isosnow.mix","snow.mix","sno.mix"],extension:".sno",newTheaterChar:"A",isoPaletteName:"isosno.pal",unitPaletteName:"unitsno.pal",overlayPaletteName:"snow.pal",libPaletteName:"libsno.pal"},{type:TheaterType.Urban,theaterIni:"urbanmd.ini",mixes:["isourbmd.mix","isourb.mix","urb.mix","urban.mix"],extension:".urb",newTheaterChar:"U",isoPaletteName:"isourb.pal",unitPaletteName:"uniturb.pal",overlayPaletteName:"urban.pal",libPaletteName:"liburb.pal"},{type:TheaterType.NewUrban,theaterIni:"urbannmd.ini",mixes:["isoubnmd.mix","isoubn.mix","ubn.mix","urbann.mix"],extension:".ubn",newTheaterChar:"N",isoPaletteName:"isoubn.pal",unitPaletteName:"unitubn.pal",overlayPaletteName:"urbann.pal",libPaletteName:"libubn.pal"},{type:TheaterType.Desert,theaterIni:"desertmd.ini",mixes:["isodesmd.mix","desert.mix","des.mix","isodes.mix"],extension:".des",newTheaterChar:"D",isoPaletteName:"isodes.pal",unitPaletteName:"unitdes.pal",overlayPaletteName:"desert.pal",libPaletteName:"libdes.pal"},{type:TheaterType.Lunar,theaterIni:"lunarmd.ini",mixes:["isolunmd.mix","isolun.mix","lun.mix","lunar.mix"],extension:".lun",newTheaterChar:"L",isoPaletteName:"isolun.pal",unitPaletteName:"unitlun.pal",overlayPaletteName:"lunar.pal",libPaletteName:"liblun.pal"}]),Engine.customRulesFileName="rulescd.ini",Engine.customArtFileName="artcd.ini",Engine.customMpModesFileName="mpmodescd.ini",Engine.shroudFileName="shroud.shp",Engine.mixinRulesFileNames=(new Map).set(MixinRulesType.NoDogEngiKills,"nodogengikills.ini"),function(e){e[e.None=0]="None",e[e.Aircraft=1]="Aircraft",e[e.Building=2]="Building",e[e.Infantry=3]="Infantry",e[e.Overlay=4]="Overlay",e[e.Smudge=5]="Smudge",e[e.Terrain=6]="Terrain",e[e.Vehicle=7]="Vehicle",e[e.Animation=8]="Animation",e[e.Projectile=9]="Projectile",e[e.VoxelAnim=10]="VoxelAnim",e[e.Debris=11]="Debris"}(ObjectType=ObjectType||{});class MapObject{constructor(e){this.type=e}isStructure(){return this.type===ObjectType.Building}isVehicle(){return this.type===ObjectType.Vehicle}isInfantry(){return this.type===ObjectType.Infantry}isAircraft(){return this.type===ObjectType.Aircraft}isTerrain(){return this.type===ObjectType.Terrain}isSmudge(){return this.type===ObjectType.Smudge}isOverlay(){return this.type===ObjectType.Overlay}isNamed(){return"name"in this}isTechno(){return"health"in this}}class NamedMapObject extends MapObject{}class Techno extends NamedMapObject{}class Structure extends Techno{constructor(){super(ObjectType.Building)}}class Vehicle extends Techno{constructor(){super(ObjectType.Vehicle)}}class Infantry extends Techno{constructor(){super(ObjectType.Infantry)}}class Aircraft extends Techno{constructor(){super(ObjectType.Aircraft)}}class Terrain extends NamedMapObject{constructor(){super(ObjectType.Terrain)}}class Smudge extends NamedMapObject{constructor(){super(ObjectType.Smudge)}}class Overlay extends MapObject{constructor(){super(ObjectType.Overlay)}}class Format80{static decode(e,t){t=new Uint8Array(t);return this.decodeInto(e,t),t}static decodeInto(e,t){let i=new DataStream(new DataView(e.buffer,e.byteOffset,e.byteLength)),r=0;for(;;){var s=i.readUint8();if(0==(128&s)){var a=i.readUint8(),n=3+((112&s)>>4);this.replicatePrevious(t,r,r-(((15&s)<<8)+a),n),r+=n}else if(0==(64&s)){n=63&s;if(0==n)return r;t.set(i.readUint8Array(n),r),r+=n}else{s=63&s;if(62==s)for(var o=i.readInt16(),l=i.readUint8(),h=r+o;r<h;r++)t[r]=l;else if(63==s){o=i.readInt16();let e=i.readInt16();if(e>=r)throw new Error(`srcIndex >= destIndex ${e} `+r);for(var c=r+o;r<c;r++)t[r]=t[e++]}else{s=3+s;let e=i.readInt16();if(e>=r)throw new Error(`srcIndex >= destIndex ${e} `+r);for(var d=r+s;r<d;r++)t[r]=t[e++]}}}}static replicatePrevious(t,i,r,s){if(i<r)throw new Error(`srcIndex > destIndex ${r} `+i);if(i-r==1)for(let e=0;e<s;e++)t[i+e]=t[i-1];else for(let e=0;e<s;e++)t[i+e]=t[r+e]}}var PixelFormat,TagRepeatType,TriggerEventType,TriggerActionType,SideType,RadarEventType,PrereqCategory,TerrainType,LandType,SpeedType,InfDeathType,PipColor,LocomotorType,MovementZone,ArmorType,LandTargeting,NavalTargeting,WeaponType,VeteranAbility,VhpScan,BuildCat,FactoryType,OccupationBits,SuperWeaponType,EventType,ZoneType,AiDifficulty,PowerupType,NotifyTick,NotifyWarpChange,SuperWeaponStatus,EffectStatus,NotifyPower,NotifySuperWeaponActivate,StanceType,TaskStatus,lzo1x=__webpack_require__(887).default;class MiniLzo{static decompress(e,t){e={inputBuffer:e,outputBuffer:null},t=lzo1x.decompress(e,{outputSize:t});if(0!==t)throw new Error("MiniLzo decode failed with code "+t);return e.outputBuffer}}class Format5{static decode(e,t,i=5){t=new Uint8Array(t);return this.decodeInto(e,t,i),t}static decodeInto(e,i,r=5){var t=i.length;let s=0,a=0;for(;a<t;){var n=e[s+1]<<8|e[s];s+=2;var o=e[s+1]<<8|e[s];if(s+=2,!n||!o)break;let t;t=80===r?Format80.decode(e.subarray(s,s+n),o):MiniLzo.decompress(e.subarray(s,s+n),o);for(let e=0;e<o;++e)i[a+e]=t[e];s+=n,a+=o}}}function getChannelCount(e){switch(e){case PixelFormat.Indexed:return 1;case PixelFormat.Rgb:return 3;case PixelFormat.Rgba:return 4;default:throw new Error("Unsupported pixel format "+e)}}!function(e){e[e.Rgb=1]="Rgb",e[e.Rgba=2]="Rgba",e[e.Indexed=3]="Indexed"}(PixelFormat=PixelFormat||{});class Bitmap{constructor(e,t,i,r=PixelFormat.Rgba){var s=getChannelCount(r);this.data=i||new Uint8Array(s*e*t),this.pixelFormat=r,this.width=e,this.height=t}drawIndexedImage(t,e,i){var r=getChannelCount(this.pixelFormat);const s=this.data;var a=this.width,n=r*a,o=r*a*this.height;let l=0+n*i+r*e,h=0;for(let e=0;e<t.height;e++){for(let e=0;e<t.width;e++){var c=t.data[h];0!==c&&0<=l&&l<o&&(s[l]=c,3<=r&&(s[l+1]=0,s[l+2]=0),4===r&&(s[l+3]=255)),l+=r,h++}l+=n-t.width*r}}}class IndexedBitmap extends Bitmap{constructor(e,t,i){super(e,t,i,PixelFormat.Indexed)}}class RgbBitmap extends Bitmap{constructor(e,t,i){super(e,t,i,PixelFormat.Rgb)}}class RgbaBitmap extends Bitmap{constructor(e,t,i){super(e,t,i,PixelFormat.Rgba)}drawRgbaImage(t,e,i){const r=this.data;var s=this.width,a=4*s,n=4*s*this.height;let o=0+a*i+4*e,l=0;for(let e=0;e<t.height;e++){for(let e=0;e<t.width;e++)0<=o&&o<n&&(r[o]=t.data[l],r[o+1]=t.data[l+1],r[o+2]=t.data[l+2],r[o+3]=t.data[l+3]),o+=4,l+=4;o+=a-4*t.width}}}!function(e){e[e.OnceAny=0]="OnceAny",e[e.OnceAll=1]="OnceAll",e[e.Repeat=2]="Repeat"}(TagRepeatType=TagRepeatType||{});class TagsReader{read(e){let t=[];for(var[i,r]of e.entries){var s=r.split(",");s.length<3?console.warn(`Invalid tag ${i}=${r}. Skipping.`):(r=Number(s[0]),void 0!==TagRepeatType[r]?(s={id:i,repeatType:r,name:s[1],triggerId:s[2]},t.push(s)):console.warn(`Invalid repeat value ${r} for tag id ${i}. Skipping.`))}return t}}!function(e){e[e.NoEvent=0]="NoEvent",e[e.EnteredBy=1]="EnteredBy",e[e.SpiedBy=2]="SpiedBy",e[e.AttackedByAny=6]="AttackedByAny",e[e.DestroyedByAny=7]="DestroyedByAny",e[e.AnyEvent=8]="AnyEvent",e[e.DestroyedAllUnits=9]="DestroyedAllUnits",e[e.DestroyedAllBuildings=10]="DestroyedAllBuildings",e[e.DestroyedAll=11]="DestroyedAll",e[e.CreditsExceed=12]="CreditsExceed",e[e.ElapsedTime=13]="ElapsedTime",e[e.MissionTimerExpired=14]="MissionTimerExpired",e[e.DestroyedBuildings=15]="DestroyedBuildings",e[e.DestroyedUnits=16]="DestroyedUnits",e[e.NoFactoriesLeft=17]="NoFactoriesLeft",e[e.BuildBuilding=19]="BuildBuilding",e[e.BuildUnit=20]="BuildUnit",e[e.BuildInfantry=21]="BuildInfantry",e[e.BuildAircraft=22]="BuildAircraft",e[e.CrossesHorizontalLine=25]="CrossesHorizontalLine",e[e.CrossesVerticalLine=26]="CrossesVerticalLine",e[e.GlobalIsSet=27]="GlobalIsSet",e[e.GlobalIsCleared=28]="GlobalIsCleared",e[e.DestroyedOrCaptured=29]="DestroyedOrCaptured",e[e.LowPower=30]="LowPower",e[e.DestroyedBridge=31]="DestroyedBridge",e[e.BuildingExists=32]="BuildingExists",e[e.ComesNearWaypoint=34]="ComesNearWaypoint",e[e.LocalIsSet=36]="LocalIsSet",e[e.LocalIsCleared=37]="LocalIsCleared",e[e.FirstDamagedCombat=38]="FirstDamagedCombat",e[e.HalfHealthCombat=39]="HalfHealthCombat",e[e.QuarterHealthCombat=40]="QuarterHealthCombat",e[e.FirstDamagedAny=41]="FirstDamagedAny",e[e.HalfHealthAny=42]="HalfHealthAny",e[e.QuarterHealthAny=43]="QuarterHealthAny",e[e.AttackedByHouse=44]="AttackedByHouse",e[e.AmbientLightBelow=45]="AmbientLightBelow",e[e.AmbientLightAbove=46]="AmbientLightAbove",e[e.ElapsedScenarioTime=47]="ElapsedScenarioTime",e[e.DestroyedOrCapturedOrInfiltrated=48]="DestroyedOrCapturedOrInfiltrated",e[e.PickupCrate=49]="PickupCrate",e[e.PickupCrateAny=50]="PickupCrateAny",e[e.RandomDelay=51]="RandomDelay",e[e.CreditsBelow=52]="CreditsBelow",e[e.SpyEnteringAsHouse=53]="SpyEnteringAsHouse",e[e.SpyEnteringAsInfantry=54]="SpyEnteringAsInfantry",e[e.DestroyedAllUnitsNaval=55]="DestroyedAllUnitsNaval",e[e.DestroyedAllUnitsLand=56]="DestroyedAllUnitsLand",e[e.BuildingNotExists=57]="BuildingNotExists"}(TriggerEventType=TriggerEventType||{}),function(e){e[e.NoAction=0]="NoAction",e[e.FireSale=9]="FireSale",e[e.TextTrigger=11]="TextTrigger",e[e.DestroyTrigger=12]="DestroyTrigger",e[e.ChangeHouse=14]="ChangeHouse",e[e.RevealMap=16]="RevealMap",e[e.RevealAroundWaypoint=17]="RevealAroundWaypoint",e[e.PlaySoundFx=19]="PlaySoundFx",e[e.PlaySpeech=21]="PlaySpeech",e[e.ForceTrigger=22]="ForceTrigger",e[e.TimerStart=23]="TimerStart",e[e.TimerStop=24]="TimerStop",e[e.TimerExtend=25]="TimerExtend",e[e.TimerShorten=26]="TimerShorten",e[e.TimerSet=27]="TimerSet",e[e.GlobalSet=28]="GlobalSet",e[e.GlobalClear=29]="GlobalClear",e[e.DestroyObject=32]="DestroyObject",e[e.AddOneTimeSuperWeapon=33]="AddOneTimeSuperWeapon",e[e.AddRepeatingSuperWeapon=34]="AddRepeatingSuperWeapon",e[e.AllChangeHouse=36]="AllChangeHouse",e[e.ResizePlayerView=40]="ResizePlayerView",e[e.PlayAnimAt=41]="PlayAnimAt",e[e.DetonateWarhead=42]="DetonateWarhead",e[e.ReshroudMap=51]="ReshroudMap",e[e.EnableTrigger=53]="EnableTrigger",e[e.DisableTrigger=54]="DisableTrigger",e[e.CreateRadarEvent=55]="CreateRadarEvent",e[e.LocalSet=56]="LocalSet",e[e.LocalClear=57]="LocalClear",e[e.SellBuilding=60]="SellBuilding",e[e.TurnOffBuilding=61]="TurnOffBuilding",e[e.TurnOnBuilding=62]="TurnOnBuilding",e[e.ApplyOneHundredDamage=63]="ApplyOneHundredDamage",e[e.ForceEnd=69]="ForceEnd",e[e.DestroyTag=70]="DestroyTag",e[e.SetAmbientStep=71]="SetAmbientStep",e[e.SetAmbientRate=72]="SetAmbientRate",e[e.SetAmbientLight=73]="SetAmbientLight",e[e.NukeStrike=95]="NukeStrike",e[e.PlaySoundFxAt=99]="PlaySoundFxAt",e[e.UnrevealAroundWaypoint=101]="UnrevealAroundWaypoint",e[e.LightningStrike=102]="LightningStrike",e[e.TimerText=103]="TimerText",e[e.CreateCrate=108]="CreateCrate",e[e.IronCurtainAt=109]="IronCurtainAt",e[e.EvictOccupiers=111]="EvictOccupiers",e[e.Cheer=113]="Cheer",e[e.StopSoundsAt=116]="StopSoundsAt"}(TriggerActionType=TriggerActionType||{});class TriggerReader{read(e,t,i,r){let s=this.readTriggers(e),{events:a,unknownEventTypes:n}=this.readEvents(t),{actions:o,unknownActionTypes:l}=this.readActions(i),h=[...r.values()],c=new Set(s);for(let t of s.values()){var d=a.get(t.id);d&&t.events.push(...d);d=o.get(t.id);d&&t.actions.push(...d),!t.attachedTriggerId||(d=s.find(e=>e.id===t.attachedTriggerId))&&(t.attachedTrigger=d,c.delete(d))}for(let t of c){var u=h.find(e=>e.triggerId===t.id);if(u){let e=t;for(;e;)e.tag=u,e=e.attachedTrigger}else{let e=t;for(;e;){console.warn(`Trigger ${e.id} has no associated tag or valid root trigger. Skipping.`);var p=s.indexOf(e);-1!==p&&s.splice(p,1),e=e.attachedTrigger}}}return{triggers:s,unknownEventTypes:n,unknownActionTypes:l}}readTriggers(e){let t=[];for(var[i,r]of e.entries){var s=r.split(",");s.length<8?console.warn(`Invalid trigger ${i}=${r}. Skipping.`):(s={id:i,houseName:s[0],attachedTriggerId:"<none>"!==s[1]?s[1]:void 0,attachedTrigger:void 0,name:s[2],disabled:Boolean(Number(s[3])),difficulties:{easy:Boolean(Number(s[4])),medium:Boolean(Number(s[5])),hard:Boolean(Number(s[6]))},events:[],actions:[],tag:void 0},t.push(s))}return t}readEvents(e){let t=new Map,s=new Set;for(var[a,i]of e.entries){let r=i.split(",");if(r.length<4)console.warn(`Invalid event ${a}=${i}. Skipping.`);else{var n=Number(r.shift());let i=[];for(let t=0;t<n;t++){var o=Number(r.shift()),l=Number(r.shift());let e=r.splice(0,2===l?2:1);void 0!==TriggerEventType[o]?(l={triggerId:a,eventIndex:t,type:o,params:[l,...e.map(e=>e||"0")]},i.push(l)):(s.add(o),console.warn(`Unknown event type ${o} for trigger id ${a}. Skipping.`))}t.set(a,i)}}return{events:t,unknownEventTypes:s}}readActions(e){let r=new Map,s=new Set;for(var[a,t]of e.entries){let i=t.split(",");if(i.length<9)console.warn(`Invalid action ${a}=${t}. Skipping.`);else{var n=Number(i.shift());if(i.length<8*n)console.warn(`Invalid action ${a}=${t}. Skipping.`);else{let t=[];for(let e=0;e<n;e++){var o=Number(i.shift()),l=i.splice(0,7);void 0!==TriggerActionType[o]?(l={triggerId:a,index:e,type:o,params:[Number(l[0]||"0"),l[1]||"0",l[2]||"0",l[3]||"0",l[4]||"0",l[5]||"0",l[6]?this.readAZActionParam(l[6]):0]},t.push(l)):(s.add(o),console.warn(`Unknown action type ${o} for trigger id "${a}". Skipping.`))}r.set(a,t)}}}return{actions:r,unknownActionTypes:s}}readAZActionParam(e){var t="Z".charCodeAt(0),i="A".charCodeAt(0),t=t-i+1;return 1<e.length?e.charCodeAt(1)-i+(e.charCodeAt(0)-i+1)*t:e.charCodeAt(0)-i}}class MapLighting{constructor(){this.level=0,this.ambient=1,this.red=1,this.green=1,this.blue=1,this.ground=0,this.forceTint=!1}read(e,t=""){return this.level=e.getNumber(t+"Level",.032),this.ambient=e.getNumber(t+"Ambient",1),this.red=e.getNumber(t+"Red",1),this.green=e.getNumber(t+"Green",1),this.blue=e.getNumber(t+"Blue",1),this.ground=e.getNumber(t+"Ground",0),this}copy(e){return this.level=e.level,this.ambient=e.ambient,this.red=e.red,this.green=e.green,this.blue=e.blue,this.ground=e.ground,this.forceTint=e.forceTint,this}}class CellTagsReader{read(e,t){let i=[];for(var[r,s]of e.entries){r={tagId:s,coords:this.readCoords(Number(r),t)};i.push(r)}return i}readCoords(e,t){t=t<4?128:1e3;return{x:e%t,y:Math.floor(e/t)}}}class Variable{constructor(e,t){this.name=e,this.value=t}clone(){return new Variable(this.name,this.value)}}class SpecialFlags{read(e){return this.initialVeteran=e.getBool("InitialVeteran"),this}}class MapFile extends IniFile{fromString(e){super.fromString(e);let t=this.getSection("Map");if(!t)throw new Error("[Map] section not found");e=t.getNumberArray("Size");if(this.fullSize={x:e[0],y:e[1],width:e[2],height:e[3]},e=t.getNumberArray("LocalSize"),this.localSize={x:e[0],y:e[1],width:e[2],height:e[3]},this.theaterType=t.getEnum("Theater",TheaterType,TheaterType.None,!0),this.theaterType===TheaterType.None)throw new Error(`Unsupported theater type "${t.getString("Theater")}"`);let i=this.getSection("Basic");e=this.iniFormat=i?.getNumber("NewINIFormat")??0;return this.readTiles(),this.readWaypoints(this.getOrCreateSection("Waypoints")),this.readStructures(this.getOrCreateSection("Structures")),this.readVehicles(),this.readInfantries(),this.readAircrafts(),this.readTerrains(this.getOrCreateSection("Terrain")),this.readOverlays(),this.readSmudges(),this.readLighting(),this.readTagsAndTriggers(),this.readCellTags(e),this.readVariableNames(),this.startingLocations=this.readStartingLocations(this.waypoints),this.specialFlags=(new SpecialFlags).read(this.getOrCreateSection("SpecialFlags")),this}fromJson(i){if(i[MapFile.artSectionPrefix]){let{[MapFile.artSectionPrefix]:e,...t}=i;this.artOverrides=new IniFile(e),i=t}return super.fromJson(i)}readStartingLocations(e){let t=[];var i;for(i of e.filter(e=>e.number<8).sort((e,t)=>e.number<t.number?-1:1))t.push({x:i.rx,y:i.ry});return t}readLighting(){var e=this.getOrCreateSection("Lighting");this.lighting=(new MapLighting).read(e),this.ionLighting=(new MapLighting).read(e,"Ion"),this.ionLighting.forceTint=!0}readTagsAndTriggers(){this.tags=(new TagsReader).read(this.getOrCreateSection("Tags"));var e=this.getOrCreateSection("Triggers"),t=this.getOrCreateSection("Events"),i=this.getOrCreateSection("Actions"),{triggers:e,unknownEventTypes:t,unknownActionTypes:i}=(new TriggerReader).read(e,t,i,this.tags);this.triggers=e,this.unknownEventTypes=t,this.unknownActionTypes=i}readCellTags(e){this.cellTags=(new CellTagsReader).read(this.getOrCreateSection("CellTags"),e)}readVariableNames(){var e,t,i=this.getOrCreateSection("VariableNames");let r=new Map;for([e,t]of i.entries){var s,a,n=Number(e);Number.isNaN(n)?console.warn(`Map [VariableNames] contains non-numeric index "${e}". Skipping.`):([s,a]=t.split(","),a=new Variable(s,Boolean(Number(a))),r.set(n,a))}this.variables=r}readTiles(){let e=this.getSection("IsoMapPack5");if(!e)throw new Error("[IsoMapPack5] section not found");var t=base64StringToUint8Array(e.getConcatenatedValues()),i=(2*this.fullSize.width-1)*this.fullSize.height,r=new Uint8Array(11*i+4);Format5.decodeInto(t,r);let s=new DataStream(r.buffer),a=2*this.fullSize.width-1;var n,o,l,h,r=this.fullSize.height,c=(e,t)=>t*a+e;this.tiles=new Array(a*r);for(let e=this.maxTileNum=0;e<i;e++){var d=s.readUint16(),u=s.readUint16(),p=Math.max(0,s.readInt16());this.maxTileNum=Math.max(this.maxTileNum,p),s.readInt16();var g=s.readUint8(),m=s.readUint8();s.readUint8();var y=d-u+this.fullSize.width-1,T=d+u-this.fullSize.width-1;0<=y&&y<2*this.fullSize.width&&0<=T&&T<2*this.fullSize.height&&(g={dx:y,dy:T,rx:d,ry:u,z:m,tileNum:p,subTile:g},this.tiles[c(y,Math.floor(T/2))]=g)}for(let t=0;t<this.fullSize.height;t++)for(let e=0;e<=2*this.fullSize.width-2;e++)this.tiles[c(e,t)]||(n=e,h=(o=2*t+e%2)-(l=(n+o)/2+1)+this.fullSize.width+1,this.tiles[c(e,t)]={dx:n,dy:o,rx:l,ry:h,z:0,tileNum:0,subTile:0})}readWaypoints(e){this.waypoints=[];for(var[t,i]of e.entries){var r;let e;isNaN(r=parseInt(t,10))||isNaN(e=parseInt(i,10))||(t=Math.floor(e/1e3),i=e-1e3*t,this.waypoints.push({number:r,rx:i,ry:t}))}}readStructures(e){this.structures=[];for(var[,t]of e.entries){t=t.split(",");if(!(t.length<=15)){let e=new Structure;e.owner=t[0],e.name=t[1],e.health=Number(t[2]),e.rx=Number(t[3]),e.ry=Number(t[4]),e.tag=this.readTagId(t[6]),e.poweredOn=Boolean(Number(t[9])),this.structures.push(e)}}}readTagId(e){return"none"!==e.toLowerCase()?e:void 0}readVehicles(){this.vehicles=[];let e=this.getSection("Units");if(e)for(var t of e.entries.values()){var i=t.split(",");if(i.length<=11)console.warn(`Invalid Vehicle entry: "${t}"`);else{let e=new Vehicle;e.owner=i[0],e.name=i[1],e.health=Number(i[2]),e.rx=Number(i[3]),e.ry=Number(i[4]),e.direction=Number(i[5]),e.tag=this.readTagId(i[7]),e.veterancy=Number(i[8]),e.onBridge="1"===i[10],this.vehicles.push(e)}}}readInfantries(){this.infantries=[];let e=this.getSection("Infantry");if(e)for(var t of e.entries.values()){var i=t.split(",");let e=new Infantry;i.length<=8?console.warn(`Invalid Infantry entry: "${t}"`):(e.owner=i[0],e.name=i[1],e.health=Number(i[2]),e.rx=Number(i[3]),e.ry=Number(i[4]),e.subCell=Number(i[5]),e.direction=Number(i[7]),e.tag=this.readTagId(i[8]),e.veterancy=Number(i[9]),e.onBridge="1"===i[11],this.infantries.push(e))}}readAircrafts(){this.aircrafts=[];let e=this.getSection("Aircraft");if(e)for(var t of e.entries.values()){t=t.split(",");let e=new Aircraft;e.owner=t[0],e.name=t[1],e.health=Number(t[2]),e.rx=Number(t[3]),e.ry=Number(t[4]),e.direction=Number(t[5]),e.tag=this.readTagId(t[7]),e.veterancy=Number(t[8]),e.onBridge="1"===t[t.length-4],this.aircrafts.push(e)}}readTerrains(e){this.terrains=[];for(var[t,i]of e.entries){t=Number(t);if(!isNaN(t)){let e=new Terrain;e.name=i,e.rx=t%1e3,e.ry=Math.floor(t/1e3),this.terrains.push(e)}}}readOverlays(){this.overlays=[],this.maxOverlayId=0;let t=this.getSection("OverlayPack");if(t){var i=base64StringToUint8Array(t.getConcatenatedValues()),r=new Uint8Array(1<<18);Format5.decodeInto(i,r,80);let e=this.getSection("OverlayDataPack");if(e){var i=base64StringToUint8Array(e.getConcatenatedValues()),s=new Uint8Array(1<<18);Format5.decodeInto(i,s,80);for(let t=0;t<this.fullSize.height;t++)for(let e=2*this.fullSize.width-2;0<=e;e--){var a=e,n=2*t+e%2,o=(a+n)/2+1,l=n-o+this.fullSize.width+1,a=o+512*l,n=r[a];if(255!==n){a=s[a];let e=new Overlay;e.id=n,e.value=a,e.rx=o,e.ry=l,this.overlays.push(e),this.maxOverlayId=Math.max(this.maxOverlayId,n)}}}else console.warn("[OverlayDataPack] section not found. Skipping.")}else console.warn("[Overlay] section not found. Skipping.")}readSmudges(){this.smudges=[];let e=this.getSection("Smudge");if(e)for(var t of e.entries.values()){var i=t.split(",");if(i.length<=2)console.warn(`Invalid Smudge entry: "${t}"`);else{let e=new Smudge;e.name=i[0],e.rx=Number(i[1]),e.ry=Number(i[2]),this.smudges.push(e)}}}decodePreviewImage(){let e=this.getSection("Preview"),t=this.getSection("PreviewPack");if(e&&t){var[,,i,r]=e.getArray("Size").map(e=>Number(e)),s=base64StringToUint8Array(t.getConcatenatedValues()),r=new RgbBitmap(i,r);return Format5.decodeInto(s,r.data),r}}}MapFile.artSectionPrefix="ART",function(e){e[e.GDI=0]="GDI",e[e.Nod=1]="Nod",e[e.ThirdSide=2]="ThirdSide",e[e.Civilian=3]="Civilian",e[e.Mutant=4]="Mutant"}(SideType=SideType||{});const sideMap=(new Map).set("GDI",SideType.GDI).set("Nod",SideType.Nod).set("Civilian",SideType.Civilian).set("Mutant",SideType.Mutant).set("ThirdSide",SideType.ThirdSide),defaultUiTooltips=new Map([["Americans","STT:PlayerSideAmerica"],["Alliance","STT:PlayerSideKorea"],["French","STT:PlayerSideFrance"],["Germans","STT:PlayerSideGermany"],["British","STT:PlayerSideBritain"],["Africans","STT:PlayerSideLibya"],["Arabs","STT:PlayerSideIraq"],["Confederation","STT:PlayerSideCuba"],["Russians","STT:PlayerSideRussia"],["YuriCountry","STT:PlayerSideYuriCountry"]]);class CountryRules{constructor(e){this.id=e}readIni(e){this.name=e.name,this.uiName=e.getString("UIName"),this.uiTooltip=e.getString("UITooltip")||defaultUiTooltips.get(this.name);var t=e.getString("Side");if(!t)throw new Error(`Missing Side for country "${this.name}"`);var i=sideMap.get(t);if(void 0===i)throw new Error(`Unknown side "${t}" for country "${this.name}"`);this.side=i,this.multiplay=e.getBool("Multiplay"),this.multiplayPassive=e.getBool("MultiplayPassive"),this.veteranAircraft=e.getArray("VeteranAircraft"),this.veteranInfantry=e.getArray("VeteranInfantry"),this.veteranUnits=e.getArray("VeteranUnits")}}class ObjectRules{static iniSpeedToLeptonsPerTick(e,t){return Math.min(256,256*e/t)}static iniRotToDegsPerTick(e){return e/256*360}constructor(e,t,i=-1,r){this.type=e,this.ini=t,this.index=i,this.generalRules=r,this.parse()}parse(){this.alphaImage=this.ini.getString("AlphaImage")||void 0,this.alternateArcticArt=this.ini.getBool("AlternateArcticArt"),this.crushable=this.ini.getBool("Crushable",this.type===ObjectType.Infantry),this.crushSound=this.ini.getString("CrushSound")||void 0,this.dontScore=this.ini.getBool("DontScore"),this.insignificant=this.ini.getBool("Insignificant"),this.legalTarget=this.ini.getBool("LegalTarget",!0),this.noShadow=this.ini.getBool("NoShadow"),this.uiName=this.ini.getString("UIName")}get name(){return this.ini.name}get imageName(){let e=this.ini.getString("Image");return e&&"null"!==e||(e=this.name),e}}ObjectRules.IMAGE_NONE="none";class WeaponRules{constructor(e){this.rules=e,this.parse()}parse(){this.ambientDamage=this.rules.getNumber("AmbientDamage"),this.anim=this.rules.getArray("Anim"),this.areaFire=this.rules.getBool("AreaFire"),this.burst=this.rules.getNumber("Burst",1),this.cellRangefinding=this.rules.getBool("CellRangefinding"),this.damage=this.rules.getNumber("Damage"),this.decloakToFire=this.rules.getBool("DecloakToFire",!0),this.fireOnce=this.rules.getBool("FireOnce"),this.isAlternateColor=this.rules.getBool("IsAlternateColor"),this.isElectricBolt=this.rules.getBool("IsElectricBolt"),this.isHouseColor=this.rules.getBool("IsHouseColor"),this.isLaser=this.rules.getBool("IsLaser"),this.isRadBeam=this.rules.getBool("IsRadBeam"),this.isSonic=this.rules.getBool("IsSonic"),this.laserDuration=this.rules.getNumber("LaserDuration"),this.limboLaunch=this.rules.getBool("LimboLaunch"),this.minimumRange=this.rules.getNumber("MinimumRange"),this.name=this.rules.name,this.neverUse=this.rules.getBool("NeverUse"),this.omniFire=this.rules.getBool("OmniFire"),this.projectile=this.rules.getString("Projectile"),this.radLevel=this.rules.getNumber("RadLevel"),this.range=this.rules.getNumber("Range"),-2===this.range&&(this.range=Number.POSITIVE_INFINITY),this.report=this.rules.getArray("Report"),this.revealOnFire=this.rules.getBool("RevealOnFire",!0),this.rof=this.rules.getNumber("ROF"),this.sabotageCursor=this.rules.getBool("SabotageCursor"),this.spawner=this.rules.getBool("Spawner");var e=this.rules.getNumber("Speed");this.iniSpeed=e,this.speed=ObjectRules.iniSpeedToLeptonsPerTick(e,100),this.suicide=this.rules.getBool("Suicide"),this.useSparkParticles=this.rules.getBool("UseSparkParticles"),this.warhead=this.rules.getString("Warhead")}}class AudioVisualRules{readIni(e){this.ini=e,this.ambientChangeRate=e.getNumber("AmbientChangeRate"),this.ambientChangeStep=e.getNumber("AmbientChangeStep"),this.behind=e.getString("Behind"),this.bridgeExplosions=e.getArray("BridgeExplosions"),this.chronoBeamColor=e.getNumberArray("ChronoBeamColor"),this.chronoBlast=e.getString("ChronoBlast"),this.chronoBlastDest=e.getString("ChronoBlastDest"),this.chronoPlacement=e.getString("ChronoPlacement"),this.chronoSparkle1=e.getString("ChronoSparkle1"),this.conditionRed=e.getNumber("ConditionRed"),this.conditionYellow=e.getNumber("ConditionYellow"),this.creditTicks=e.getArray("CreditTicks"),this.extraAircraftLight=e.getNumber("ExtraAircraftLight"),this.extraInfantryLight=e.getNumber("ExtraInfantryLight"),this.extraUnitLight=e.getNumber("ExtraUnitLight");let t=e.getString("DamageFireTypes");t=t||"FIRE01,FIRE02,FIRE03",this.fireNames=t.split(/\.|,/).filter(e=>""!==e),this.flyerHelper=e.getString("FlyerHelper"),this.gravity=e.getNumber("Gravity"),this.idleActionFrequency=60*e.getNumber("IdleActionFrequency"),this.impactLandSound=e.getString("ImpactLandSound")||void 0,this.impactWaterSound=e.getString("ImpactWaterSound")||void 0,this.infantryExplode=e.getString("InfantryExplode"),this.flamingInfantry=e.getString("FlamingInfantry"),this.infantryHeadPop=e.getString("InfantryHeadPop"),this.infantryNuked=e.getString("InfantryNuked"),this.ironCurtainInvokeAnim=e.getString("IronCurtainInvokeAnim"),this.messageDuration=e.getNumber("MessageDuration",10),this.metallicDebris=e.getArray("MetallicDebris"),this.nukeTakeOff=e.getString("NukeTakeOff"),this.deadBodies=e.getArray("DeadBodies"),this.wake=e.getString("Wake"),this.parachute=e.getString("Parachute"),this.moveFlash=e.getString("MoveFlash"),this.warpOut=e.getString("WarpOut"),this.warpAway=e.getString("WarpAway"),this.weaponNullifyAnim=e.getString("WeaponNullifyAnim"),this.weatherConClouds=e.getArray("WeatherConClouds"),this.weatherConBoltExplosion=e.getString("WeatherConBoltExplosion"),this.weatherConBolts=e.getArray("WeatherConBolts")}}!function(e){e[e.GenericCombat=0]="GenericCombat",e[e.GenericNonCombat=1]="GenericNonCombat",e[e.DropZone=2]="DropZone",e[e.BaseUnderAttack=3]="BaseUnderAttack",e[e.HarvesterUnderAttack=4]="HarvesterUnderAttack",e[e.EnemyObjectSensed=5]="EnemyObjectSensed"}(RadarEventType=RadarEventType||{});class RadarRules{readIni(e){return this.eventSuppressionDistances=e.getNumberArray("RadarEventSuppressionDistances"),this.eventVisibilityDurations=e.getNumberArray("RadarEventVisibilityDurations"),this.eventDurations=e.getNumberArray("RadarEventDurations"),this.flashFrameTime=e.getNumber("FlashFrameTime"),this.combatFlashTime=e.getNumber("RadarCombatFlashTime"),this.eventMinRadius=e.getNumber("RadarEventMinRadius"),this.eventSpeed=e.getNumber("RadarEventSpeed"),this.eventRotationSpeed=e.getNumber("RadarEventRotationSpeed"),this.eventColorSpeed=e.getNumber("RadarEventColorSpeed"),this}getEventSuppresionDistance(e){if(e>this.eventSuppressionDistances.length-1)throw new RangeError("No event suppression distance is defined for type "+RadarEventType[e]);return this.eventSuppressionDistances[e]}getEventVisibilityDuration(e){if(e>this.eventVisibilityDurations.length-1)throw new RangeError("No event visibility duration is defined for type "+RadarEventType[e]);return this.eventVisibilityDurations[e]}getEventDuration(e){if(e>this.eventDurations.length-1)throw new RangeError("No event duration is defined for type "+RadarEventType[e]);return this.eventDurations[e]}}class RepairRules{readIni(e){return this.reloadRate=e.getNumber("ReloadRate"),this.repairPercent=e.getNumber("RepairPercent"),this.repairRate=e.getNumber("RepairRate"),this.repairStep=e.getNumber("RepairStep"),this.uRepairRate=e.getNumber("URepairRate"),this.iRepairRate=e.getNumber("IRepairRate"),this.iRepairStep=e.getNumber("IRepairStep"),this}}class VeteranRules{readIni(e){return this.veteranRatio=e.getNumber("VeteranRatio",3),this.veteranCombat=e.getNumber("VeteranCombat",1),this.veteranSpeed=e.getNumber("VeteranSpeed",1),this.veteranSight=Math.max(1,e.getNumber("VeteranSight",1)),this.veteranArmor=e.getNumber("VeteranArmor",1),this.veteranROF=e.getNumber("VeteranROF",1),this.veteranCap=e.getNumber("VeteranCap",2),this.initialVeteran=e.getBool("InitialVeteran"),this}}class CrewRules{readIni(e){return this.alliedCrew=e.getString("AlliedCrew"),this.alliedSurvivorDivisor=e.getNumber("AlliedSurvivorDivisor"),this.crewEscape=e.getNumber("CrewEscape"),this.sovietCrew=e.getString("SovietCrew"),this.sovietSurvivorDivisor=e.getNumber("SovietSurvivorDivisor"),this.survivorRate=e.getNumber("SurvivorRate"),this.thirdCrew=e.getString("ThirdCrew"),this.thirdSurvivorDivisor=e.getNumber("ThirdSurvivorDivisor"),this}}class PrismRules{readIni(e){return this.type=e.getString("PrismType"),this.supportHeight=e.getNumber("PrismSupportHeight"),this.supportMax=e.getNumber("PrismSupportMax"),this.supportModifier=e.getNumber("PrismSupportModifier",1),this}}class ThreatRules{readIni(e){return this.myEffectivenessCoefficientDefault=e.getNumber("MyEffectivenessCoefficientDefault"),this.targetEffectivenessCoefficientDefault=e.getNumber("TargetEffectivenessCoefficientDefault"),this.targetSpecialThreatCoefficientDefault=e.getNumber("TargetSpecialThreatCoefficientDefault"),this.targetStrengthCoefficientDefault=e.getNumber("TargetStrengthCoefficientDefault"),this.targetDistanceCoefficientDefault=e.getNumber("TargetDistanceCoefficientDefault"),this}}class ParadropRules{readIni(e){if(this.allyParaDrop=this.readParadropSquad(e.getArray("AllyParaDropInf"),e.getNumberArray("AllyParaDropNum"),"Ally"),this.amerParaDrop=this.readParadropSquad(e.getArray("AmerParaDropInf"),e.getNumberArray("AmerParaDropNum"),"Amer"),this.sovParaDrop=this.readParadropSquad(e.getArray("SovParaDropInf"),e.getNumberArray("SovParaDropNum"),"Sov"),this.yuriParaDrop=this.readParadropSquad(e.getArray("YuriParaDropInf"),e.getNumberArray("YuriParaDropNum"),"Yuri"),this.paradropPlane=e.getString("ParadropPlane"),!this.paradropPlane)throw new Error("Missing rules [General]->ParadropPlane");return this.paradropRadius=e.getNumber("ParadropRadius"),this}readParadropSquad(t,i,e){if(t.length!==i.length)throw new RangeError(`${e}ParaDropInf/Num size mismatch (${t.length}, ${i.length})`);let r=[];for(let e=0;e<t.length;++e)0<i[e]&&r.push({inf:t[e],num:i[e]});return r}getParadropSquads(e){switch(e){case SideType.GDI:return this.allyParaDrop;case SideType.Nod:return this.sovParaDrop;case SideType.ThirdSide:return this.yuriParaDrop;default:throw new Error(`Unhandled side type "${e}"`)}}}class LightningStormRules{readIni(e){return this.deferment=e.getNumber("LightningDeferment"),this.damage=e.getNumber("LightningDamage"),this.duration=e.getNumber("LightningStormDuration"),this.warhead=e.getString("LightningWarhead"),this.hitDelay=e.getNumber("LightningHitDelay"),this.scatterDelay=e.getNumber("LightningScatterDelay"),this.cellSpread=e.getNumber("LightningCellSpread"),this.separation=e.getNumber("LightningSeparation"),this}}class MissileRules{}class V3RocketRules extends MissileRules{readIni(e){return this.pauseFrames=e.getNumber("V3RocketPauseFrames"),this.tiltFrames=e.getNumber("V3RocketTiltFrames"),this.pitchInitial=e.getNumber("V3RocketPitchInitial"),this.pitchFinal=e.getNumber("V3RocketPitchFinal"),this.turnRate=e.getNumber("V3RocketTurnRate"),this.acceleration=e.getNumber("V3RocketAcceleration"),this.altitude=e.getNumber("V3RocketAltitude"),this.damage=e.getNumber("V3RocketDamage"),this.eliteDamage=e.getNumber("V3RocketEliteDamage"),this.bodyLength=e.getNumber("V3RocketBodyLength"),this.lazyCurve=e.getBool("V3RocketLazyCurve"),this.type=e.getString("V3RocketType"),this}}class DMislRules extends MissileRules{readIni(e){return this.pauseFrames=e.getNumber("DMislPauseFrames"),this.tiltFrames=e.getNumber("DMislTiltFrames"),this.pitchInitial=e.getNumber("DMislPitchInitial"),this.pitchFinal=e.getNumber("DMislPitchFinal"),this.turnRate=e.getNumber("DMislTurnRate"),this.acceleration=e.getNumber("DMislAcceleration"),this.altitude=e.getNumber("DMislAltitude"),this.damage=e.getNumber("DMislDamage"),this.eliteDamage=e.getNumber("DMislEliteDamage"),this.bodyLength=e.getNumber("DMislBodyLength"),this.lazyCurve=e.getBool("DMislLazyCurve"),this.type=e.getString("DMislType"),this}}class HoverRules{readIni(e){return this.height=e.getNumber("HoverHeight"),this.dampen=e.getNumber("HoverDampen"),this.bob=e.getNumber("HoverBob"),this.boost=e.getNumber("HoverBoost"),this.acceleration=e.getNumber("HoverAcceleration"),this.brake=e.getNumber("HoverBrake"),this}}!function(e){e[e.Power=0]="Power",e[e.Factory=1]="Factory",e[e.Barracks=2]="Barracks",e[e.Radar=3]="Radar",e[e.Tech=4]="Tech",e[e.Proc=5]="Proc"}(PrereqCategory=PrereqCategory||{});const prereqCategIniKeys=(new Map).set(PrereqCategory.Power,"PrerequisitePower").set(PrereqCategory.Factory,"PrerequisiteFactory").set(PrereqCategory.Barracks,"PrerequisiteBarracks").set(PrereqCategory.Radar,"PrerequisiteRadar").set(PrereqCategory.Tech,"PrerequisiteTech").set(PrereqCategory.Proc,"PrerequisiteProc");class GeneralRules{constructor(){this.prereqCategories=new Map}readIni(e){this.aircraftFogReveal=e.getNumber("AircraftFogReveal"),this.alliedDisguise=e.getString("AlliedDisguise"),this.baseUnit=e.getArray("BaseUnit"),this.bridgeVoxelMax=e.getNumber("BridgeVoxelMax"),this.buildSpeed=e.getFixed("BuildSpeed"),this.buildupTime=e.getNumber("BuildupTime"),this.chronoDelay=e.getNumber("ChronoDelay"),this.chronoDistanceFactor=e.getNumber("ChronoDistanceFactor",32),this.chronoHarvTooFarDistance=e.getNumber("ChronoHarvTooFarDistance"),this.chronoMinimumDelay=e.getNumber("ChronoMinimumDelay"),this.chronoRangeMinimum=e.getNumber("ChronoRangeMinimum"),this.chronoTrigger=e.getBool("ChronoTrigger",!0),this.cliffBackImpassability=e.getNumber("CliffBackImpassability",2),this.cloakDelay=e.getNumber("CloakDelay"),this.closeEnough=e.getNumber("CloseEnough"),this.crew=(new CrewRules).readIni(e),this.defaultMirageDisguises=e.getArray("DefaultMirageDisguises"),this.dMisl=(new DMislRules).readIni(e),this.dropPodWeapon=e.getString("DropPodWeapon"),this.engineer=e.getString("Engineer"),this.engineerCaptureLevel=e.getFixed("EngineerCaptureLevel",.25),this.engineerDamage=e.getFixed("EngineerDamage",.437),this.engineerAlwaysCaptureTech=e.getBool("EngineerAlwaysCaptureTech",!0),this.flightLevel=e.getNumber("FlightLevel"),this.guardAreaTargetingDelay=e.getNumber("GuardAreaTargetingDelay"),this.harvesterTooFarDistance=e.getNumber("HarvesterTooFarDistance"),this.harvesterUnit=e.getArray("HarvesterUnit"),this.hover=(new HoverRules).readIni(e),this.infantryBlinkDisguiseTime=e.getNumber("InfantryBlinkDisguiseTime"),this.lightningStorm=(new LightningStormRules).readIni(e),this.lowPowerPenaltyModifier=e.getNumber("LowPowerPenaltyModifier",1),this.minLowPowerProductionSpeed=e.getFixed("MinLowPowerProductionSpeed",.5),this.maxLowPowerProductionSpeed=e.getFixed("MaxLowPowerProductionSpeed",1),this.maximumCheerRate=e.getNumber("MaximumCheerRate"),this.maximumQueuedObjects=e.getNumber("MaximumQueuedObjects"),this.maxWaypointPathLength=e.getNumber("MaxWaypointPathLength"),this.multipleFactory=e.getFixed("MultipleFactory",1),this.normalTargetingDelay=e.getNumber("NormalTargetingDelay"),this.padAircraft=e.getArray("PadAircraft"),this.parachuteMaxFallRate=e.getNumber("ParachuteMaxFallRate"),this.paradrop=(new ParadropRules).readIni(e),this.prism=(new PrismRules).readIni(e),this.purifierBonus=e.getNumber("PurifierBonus"),this.radar=(new RadarRules).readIni(e),this.refundPercent=clamp(e.getNumber("RefundPercent"),0,1),this.repair=(new RepairRules).readIni(e),this.returnStructures=e.getBool("ReturnStructures"),this.revealTriggerRadius=Math.min(10,e.getNumber("RevealTriggerRadius")),this.shipSinkingWeight=e.getNumber("ShipSinkingWeight"),this.sovietDisguise=e.getString("SovietDisguise"),this.spyMoneyStealPercent=e.getNumber("SpyMoneyStealPercent"),this.spyPowerBlackout=e.getNumber("SpyPowerBlackout"),this.technician=e.getString("Technician"),this.thirdDisguise=e.getString("ThirdDisguise"),this.threat=(new ThreatRules).readIni(e),this.treeStrength=e.getNumber("TreeStrength"),this.unitsUnsellable=e.getBool("UnitsUnsellable"),this.v3Rocket=(new V3RocketRules).readIni(e),this.veteran=(new VeteranRules).readIni(e),this.wallBuildSpeedCoefficient=e.getFixed("WallBuildSpeedCoefficient"),this.readPrereqCategories(e)}readPrereqCategories(e){for(var[t,i]of prereqCategIniKeys){if(!e.has(i))throw new Error(`Missing prerequisite category ${i} in [General] section`);this.prereqCategories.set(t,e.getArray(i))}}getMissileRules(e){switch(e){case this.v3Rocket.type:return this.v3Rocket;case this.dMisl.type:return this.dMisl;default:throw new Error(`Unsupported missile type "${e}"`)}}}!function(e){e[e.Default=0]="Default",e[e.Tunnel=5]="Tunnel",e[e.Railroad=6]="Railroad",e[e.Rock1=7]="Rock1",e[e.Rock2=8]="Rock2",e[e.Water=9]="Water",e[e.Shore=10]="Shore",e[e.Pavement=11]="Pavement",e[e.Dirt=12]="Dirt",e[e.Clear=13]="Clear",e[e.Rough=14]="Rough",e[e.Cliff=15]="Cliff"}(TerrainType=TerrainType||{}),function(e){e[e.Clear=0]="Clear",e[e.Road=1]="Road",e[e.Rock=2]="Rock",e[e.Beach=3]="Beach",e[e.Rough=4]="Rough",e[e.Railroad=5]="Railroad",e[e.Weeds=6]="Weeds",e[e.Water=7]="Water",e[e.Wall=8]="Wall",e[e.Tiberium=9]="Tiberium",e[e.Cliff=10]="Cliff"}(LandType=LandType||{});const terrainToLandType=new Map([[TerrainType.Default,LandType.Clear],[TerrainType.Clear,LandType.Clear],[TerrainType.Tunnel,LandType.Cliff],[TerrainType.Railroad,LandType.Railroad],[TerrainType.Rock1,LandType.Rock],[TerrainType.Rock2,LandType.Rock],[TerrainType.Water,LandType.Water],[TerrainType.Shore,LandType.Beach],[TerrainType.Pavement,LandType.Road],[TerrainType.Dirt,LandType.Road],[TerrainType.Rough,LandType.Rough],[TerrainType.Cliff,LandType.Cliff]]);function getLandType(e){if(!terrainToLandType.has(e))throw new Error("Unknown terrain type "+e);return terrainToLandType.get(e)}!function(e){e[e.Foot=0]="Foot",e[e.Track=1]="Track",e[e.Wheel=2]="Wheel",e[e.Hover=3]="Hover",e[e.Float=4]="Float",e[e.FloatBeach=5]="FloatBeach",e[e.Amphibious=6]="Amphibious",e[e.Winged=7]="Winged"}(SpeedType=SpeedType||{});class LandRules{constructor(){this.speedModifiers=new Map}readIni(t){return this.buildable=t.getBool("Buildable",!1),[...t.entries.keys()].forEach(e=>{void 0!==SpeedType[e]&&this.speedModifiers.set(SpeedType[e],t.getNumber(e))}),this}getSpeedModifier(e){if(e===SpeedType.Foot&&0===this.speedModifiers.get(SpeedType.Track))return 0;let t=this.speedModifiers.get(e);return void 0===t&&(t=1),e!==SpeedType.Track&&e!==SpeedType.Wheel&&0<t&&(t=1),t}}!function(e){e[e.None=0]="None",e[e.Gunfire=1]="Gunfire",e[e.Explode=2]="Explode",e[e.ExplodeAlt=3]="ExplodeAlt",e[e.Fire=4]="Fire",e[e.Electro=5]="Electro",e[e.HeadExplode=6]="HeadExplode",e[e.Nuke=7]="Nuke"}(InfDeathType=InfDeathType||{});class WarheadRules{constructor(e){this.rules=e,this.verses=new Map,this.parse()}get name(){return this.rules.name}parse(){this.affectsAllies=this.rules.getBool("AffectsAllies",!0),this.animList=this.rules.getArray("AnimList"),this.bombDisarm=this.rules.getBool("BombDisarm"),this.bullets=this.rules.getBool("Bullets"),this.causesDelayKill=this.rules.getBool("CausesDelayKill"),this.cellSpread=this.rules.getNumber("CellSpread"),this.conventional=this.rules.getBool("Conventional"),this.culling=this.rules.getBool("Culling"),this.delayKillAtMax=this.rules.getNumber("DelayKillAtMax"),this.delayKillFrames=this.rules.getNumber("DelayKillFrames"),this.electricAssault=this.rules.getBool("ElectricAssault"),this.emEffect=this.rules.getBool("EMEffect"),this.infDeath=this.rules.getEnumNumeric("InfDeath",InfDeathType,InfDeathType.None),this.ivanBomb=this.rules.getBool("IvanBomb"),this.makesDisguise=this.rules.getBool("MakesDisguise"),this.mindControl=this.rules.getBool("MindControl"),this.nukeMaker=this.rules.getBool("NukeMaker"),this.paralyzes=this.rules.getNumber("Paralyzes"),this.parasite=this.rules.getBool("Parasite"),this.percentAtMax=this.rules.getNumber("PercentAtMax",1),this.proneDamage=this.rules.getFixed("ProneDamage",1),this.psychicDamage=this.rules.getBool("PsychicDamage"),this.radiation=this.rules.getBool("Radiation"),this.rocker=this.rules.getBool("Rocker"),this.sonic=this.rules.getBool("Sonic"),this.temporal=this.rules.getBool("Temporal");let e=this.rules.getFixedArray("Verses");e.forEach((e,t)=>this.verses.set(t,e)),this.wallAbsoluteDestroyer=this.rules.getBool("WallAbsoluteDestroyer"),this.wall=this.rules.getBool("Wall"),this.wood=this.rules.getBool("Wood")}}class ProjectileRules extends ObjectRules{parse(){super.parse();var e=this.ini.getNumber("ROT",0);let t=this.ini.getNumber("Acceleration");1!==e||t||(t=Number.POSITIVE_INFINITY),t=t||3,this.acceleration=t,this.arcing=this.ini.getBool("Arcing"),this.courseLockDuration=this.ini.getNumber("CourseLockDuration"),this.detonationAltitude=this.ini.getNumber("DetonationAltitude"),this.firersPalette=this.ini.getBool("FirersPalette"),this.flakScatter=this.ini.getBool("FlakScatter"),this.inaccurate=this.ini.getBool("Inaccurate"),this.inviso=this.ini.getBool("Inviso"),this.isAntiAir=this.ini.getBool("AA"),this.isAntiGround=this.ini.getBool("AG",!0),this.level=this.ini.getBool("Level"),this.rot=ObjectRules.iniRotToDegsPerTick(e),this.iniRot=e,this.shadow=this.ini.getBool("Shadow",!0),this.shrapnelWeapon=this.ini.getString("ShrapnelWeapon")||void 0,this.shrapnelCount=this.ini.getNumber("ShrapnelCount"),this.subjectToCliffs=this.ini.getBool("SubjectToCliffs"),this.subjectToElevation=this.ini.getBool("SubjectToElevation"),this.subjectToWalls=this.ini.getBool("SubjectToWalls"),this.vertical=this.ini.getBool("Vertical")}}!function(e){e[e.Green=0]="Green",e[e.Yellow=1]="Yellow",e[e.White=2]="White",e[e.Red=3]="Red",e[e.Blue=4]="Blue"}(PipColor=PipColor||{}),function(e){e[e.Statue=0]="Statue",e[e.Aircraft=1]="Aircraft",e[e.Chrono=2]="Chrono",e[e.Hover=3]="Hover",e[e.Infantry=4]="Infantry",e[e.Jumpjet=5]="Jumpjet",e[e.Missile=6]="Missile",e[e.Ship=7]="Ship",e[e.Vehicle=8]="Vehicle"}(LocomotorType=LocomotorType||{});const locomotorTypesByClsId=new Map([["{4A582746-9839-11d1-B709-00A024DDAFD1}",LocomotorType.Aircraft],["{4A582747-9839-11d1-B709-00A024DDAFD1}",LocomotorType.Chrono],["{4A582742-9839-11d1-B709-00A024DDAFD1}",LocomotorType.Hover],["{4A582744-9839-11d1-B709-00A024DDAFD1}",LocomotorType.Infantry],["{92612C46-F71F-11d1-AC9F-006008055BB5}",LocomotorType.Jumpjet],["{B7B49766-E576-11d3-9BD9-00104B972FE8}",LocomotorType.Missile],["{2BEA74E1-7CCA-11d3-BE14-00104B62A16C}",LocomotorType.Ship],["{4A582741-9839-11d1-B709-00A024DDAFD1}",LocomotorType.Vehicle]]),defaultSpeedsByLocomotor=new Map([[LocomotorType.Infantry,SpeedType.Foot],[LocomotorType.Ship,SpeedType.Float],[LocomotorType.Hover,SpeedType.Hover],[LocomotorType.Jumpjet,SpeedType.Winged],[LocomotorType.Aircraft,SpeedType.Winged],[LocomotorType.Missile,SpeedType.Winged]]);!function(e){e[e.Amphibious=0]="Amphibious",e[e.AmphibiousCrusher=1]="AmphibiousCrusher",e[e.AmphibiousDestroyer=2]="AmphibiousDestroyer",e[e.Crusher=3]="Crusher",e[e.CrusherAll=4]="CrusherAll",e[e.Destroyer=5]="Destroyer",e[e.Fly=6]="Fly",e[e.Infantry=7]="Infantry",e[e.InfantryDestroyer=8]="InfantryDestroyer",e[e.Normal=9]="Normal",e[e.Subterranean=10]="Subterranean",e[e.Water=11]="Water"}(MovementZone=MovementZone||{}),function(e){e[e.None=0]="None",e[e.Flak=1]="Flak",e[e.Plate=2]="Plate",e[e.Light=3]="Light",e[e.Medium=4]="Medium",e[e.Heavy=5]="Heavy",e[e.Wood=6]="Wood",e[e.Steel=7]="Steel",e[e.Concrete=8]="Concrete",e[e.Special_1=9]="Special_1",e[e.Special_2=10]="Special_2"}(ArmorType=ArmorType||{}),function(e){e[e.LandOk=0]="LandOk",e[e.LandNotOk=1]="LandNotOk",e[e.LandSecondary=2]="LandSecondary"}(LandTargeting=LandTargeting||{}),function(e){e[e.UnderwaterNever=0]="UnderwaterNever",e[e.UnderwaterSecondary=1]="UnderwaterSecondary",e[e.UnderwaterOnly=2]="UnderwaterOnly",e[e.OrganicSecondary=3]="OrganicSecondary",e[e.SealSpecial=4]="SealSpecial",e[e.NavalAll=5]="NavalAll",e[e.NavalNone=6]="NavalNone"}(NavalTargeting=NavalTargeting||{}),function(e){e[e.Primary=0]="Primary",e[e.Secondary=1]="Secondary",e[e.DeathWeapon=2]="DeathWeapon"}(WeaponType=WeaponType||{}),function(e){e[e.FASTER=0]="FASTER",e[e.STRONGER=1]="STRONGER",e[e.FIREPOWER=2]="FIREPOWER",e[e.SCATTER=3]="SCATTER",e[e.ROF=4]="ROF",e[e.SIGHT=5]="SIGHT",e[e.SELF_HEAL=6]="SELF_HEAL",e[e.CLOAK=7]="CLOAK",e[e.EXPLODES=8]="EXPLODES",e[e.RADAR_INVISIBLE=9]="RADAR_INVISIBLE",e[e.SENSORS=10]="SENSORS",e[e.FEARLESS=11]="FEARLESS",e[e.C4=12]="C4",e[e.GUARD_AREA=13]="GUARD_AREA",e[e.CRUSHER=14]="CRUSHER"}(VeteranAbility=VeteranAbility||{}),function(e){e[e.None=0]="None",e[e.Normal=1]="Normal",e[e.Strong=2]="Strong"}(VhpScan=VhpScan||{}),function(e){e[e.Combat=0]="Combat",e[e.Tech=1]="Tech",e[e.Resource=2]="Resource",e[e.Power=3]="Power"}(BuildCat=BuildCat||{}),function(e){e[e.None=0]="None",e[e.BuildingType=1]="BuildingType",e[e.InfantryType=2]="InfantryType",e[e.UnitType=3]="UnitType",e[e.NavalUnitType=4]="NavalUnitType",e[e.AircraftType=5]="AircraftType"}(FactoryType=FactoryType||{});class TechnoRules extends ObjectRules{constructor(e,t,i,r){super(e,t,i,r)}parse(){super.parse(),this.owner=this.ini.getArray("Owner");var e=this.ini.getNumber("AIBasePlanningSide");this.aiBasePlanningSide=-1!==e&&void 0!==SideType[e]?e:void 0,this.requiredHouses=this.ini.getArray("RequiredHouses"),this.forbiddenHouses=this.ini.getArray("ForbiddenHouses"),this.requiresStolenAlliedTech=this.ini.getBool("RequiresStolenAlliedTech"),this.requiresStolenSovietTech=this.ini.getBool("RequiresStolenSovietTech"),this.requiresStolenThirdTech=this.ini.getBool("RequiresStolenThirdTech"),this.techLevel=this.ini.getNumber("TechLevel",-1),this.cost=this.ini.getNumber("Cost"),this.points=this.ini.getNumber("Points"),this.power=this.ini.getNumber("Power"),this.powered=this.ini.getBool("Powered"),this.prerequisite=this.ini.getArray("Prerequisite"),this.prerequisiteOverride=this.ini.getArray("PrerequisiteOverride"),this.soylent=this.ini.getNumber("Soylent"),this.crateGoodie=this.ini.getBool("CrateGoodie"),this.buildCat=this.ini.getEnum("BuildCat",BuildCat,BuildCat.Combat),this.adjacent=this.ini.getNumber("Adjacent",1),this.baseNormal=this.ini.getBool("BaseNormal",!0),this.buildLimit=this.ini.getNumber("BuildLimit",Number.POSITIVE_INFINITY),this.airRangeBonus=this.ini.getNumber("AirRangeBonus"),this.guardRange=this.ini.getNumber("GuardRange"),this.defaultToGuardArea=this.ini.getBool("DefaultToGuardArea"),this.eligibileForAllyBuilding=this.ini.getBool("EligibileForAllyBuilding"),this.numberImpassableRows=this.ini.getNumber("NumberImpassableRows"),this.bridgeRepairHut=this.ini.getBool("BridgeRepairHut"),this.constructionYard=this.ini.getBool("ConstructionYard"),this.refinery=this.ini.getBool("Refinery"),this.unitRepair=this.ini.getBool("UnitRepair"),this.unitReload=this.ini.getBool("UnitReload"),this.unitSell=this.ini.getBool("UnitSell"),this.isBaseDefense=this.ini.getBool("IsBaseDefense"),this.superWeapon=this.parseWeaponName(this.ini.getString("SuperWeapon")),this.chargedAnimTime=this.ini.getNumber("ChargedAnimTime");var t=this.ini.getBool("Naval");this.naval=t,this.underwater=this.ini.getBool("Underwater"),this.waterBound=this.ini.getBool("WaterBound"),this.orePurifier=this.ini.getBool("OrePurifier"),this.cloning=this.ini.getBool("Cloning"),this.grinding=this.ini.getBool("Grinding"),this.nukeSilo=this.ini.getBool("NukeSilo"),this.repairable=this.ini.getBool("Repairable",this.type===ObjectType.Building),this.clickRepairable=this.ini.getBool("ClickRepairable",this.type===ObjectType.Building),this.unsellable=this.ini.getBool("Unsellable",this.type!==ObjectType.Building&&this.generalRules.unitsUnsellable),this.returnable=this.ini.getBool("Returnable",this.generalRules.returnStructures),this.gdiBarracks=this.ini.getBool("GDIBarracks"),this.nodBarracks=this.ini.getBool("NODBarracks"),this.numberOfDocks=this.ini.getNumber("NumberOfDocks"),this.unitRepair&&!this.numberOfDocks&&(this.numberOfDocks=1),this.factory=this.ini.getEnum("Factory",FactoryType,FactoryType.None),this.factory===FactoryType.UnitType&&t&&(this.factory=FactoryType.NavalUnitType),this.weaponsFactory=this.ini.getBool("WeaponsFactory"),this.helipad=this.ini.getBool("Helipad"),this.hospital=this.ini.getBool("Hospital"),this.landTargeting=this.ini.getEnumNumeric("LandTargeting",LandTargeting,LandTargeting.LandOk),this.navalTargeting=this.ini.getEnumNumeric("NavalTargeting",NavalTargeting,NavalTargeting.UnderwaterNever),this.tooBigToFitUnderBridge=this.ini.getBool("TooBigToFitUnderBridge",this.type===ObjectType.Building),this.canBeOccupied=this.ini.getBool("CanBeOccupied"),this.maxNumberOccupants=this.ini.getNumber("MaxNumberOccupants"),this.leaveRubble=this.ini.getBool("LeaveRubble"),this.undeploysInto=this.ini.getString("UndeploysInto"),this.deploysInto=this.ini.getString("DeploysInto"),this.deployTime=this.ini.getNumber("DeployTime"),this.capturable=this.ini.getBool("Capturable"),this.spyable=this.ini.getBool("Spyable"),this.needsEngineer=this.ini.getBool("NeedsEngineer"),this.c4=this.ini.getBool("C4"),this.canC4=this.ini.getBool("CanC4",!0),this.eligibleForDelayKill=this.ini.getBool("EligibleForDelayKill"),this.produceCashStartup=this.ini.getNumber("ProduceCashStartup"),this.produceCashAmount=this.ini.getNumber("ProduceCashAmount"),this.produceCashDelay=this.ini.getNumber("ProduceCashDelay"),this.explosion=this.ini.getArray("Explosion"),this.explodes=this.ini.getBool("Explodes"),this.ifvMode=this.ini.getNumber("IFVMode"),this.turretIndexesByIfvMode=this.parseTurretIndexes(),this.turret=this.ini.getBool("Turret"),this.turretCount=this.ini.getNumber("TurretCount",this.turret?1:0),this.turretAnim=this.ini.getString("TurretAnim"),this.turretAnimIsVoxel=this.ini.getBool("TurretAnimIsVoxel"),this.turretAnimX=this.ini.getNumber("TurretAnimX"),this.turretAnimY=this.ini.getNumber("TurretAnimY"),this.turretAnimZAdjust=this.ini.getNumber("TurretAnimZAdjust"),this.isChargeTurret=this.ini.getBool("IsChargeTurret"),this.overpowerable=this.ini.getBool("Overpowerable"),this.freeUnit=this.ini.getString("FreeUnit"),this.primary=this.parseWeaponName(this.ini.getString("Primary")),this.secondary=this.parseWeaponName(this.ini.getString("Secondary")),this.elitePrimary=this.parseWeaponName(this.ini.getString("ElitePrimary")),this.eliteSecondary=this.parseWeaponName(this.ini.getString("EliteSecondary")),this.weaponCount=this.ini.getNumber("WeaponCount"),this.deathWeapon=this.parseWeaponName(this.ini.getString("DeathWeapon")),this.deathWeaponDamageModifier=this.ini.getNumber("DeathWeaponDamageModifier",1),this.occupyWeapon=this.parseWeaponName(this.ini.getString("OccupyWeapon")),this.eliteOccupyWeapon=this.parseWeaponName(this.ini.getString("EliteOccupyWeapon")),this.veteranAbilities=new Set(this.ini.getEnumArray("VeteranAbilities",VeteranAbility)),this.eliteAbilities=new Set([...this.veteranAbilities,...this.ini.getEnumArray("EliteAbilities",VeteranAbility)]),this.selfHealing=this.ini.getBool("SelfHealing"),this.wall=this.ini.getBool("Wall"),this.gate=this.ini.getBool("Gate"),this.armor=this.ini.getEnum("Armor",ArmorType,ArmorType.None,!0),this.strength=Math.floor(this.ini.getNumber("Strength")),this.immune=this.ini.getBool("Immune"),this.immuneToRadiation=this.ini.getBool("ImmuneToRadiation"),this.immuneToPsionics=this.ini.getBool("ImmuneToPsionics"),this.typeImmune=this.ini.getBool("TypeImmune"),this.damageSelf=this.ini.getBool("DamageSelf"),this.warpable=this.ini.getBool("Warpable",!0),this.isTilter=this.ini.getBool("IsTilter",!0),this.walkRate=this.ini.getNumber("WalkRate",1),this.idleRate=this.ini.getNumber("IdleRate",0),this.noSpawnAlt=this.ini.getBool("NoSpawnAlt"),this.crusher=this.ini.getBool("Crusher"),this.consideredAircraft=this.ini.getBool("ConsideredAircraft"),this.crashable=this.ini.getBool("Crashable");var i=this.ini.getBool("Landable");this.landable=i,this.airportBound=this.ini.getBool("AirportBound"),this.balloonHover=this.ini.getBool("BalloonHover"),this.hoverAttack=this.ini.getBool("HoverAttack"),this.omniFire=this.ini.getBool("OmniFire"),this.fighter=this.ini.getBool("Fighter"),this.flightLevel=this.ini.getNumber("FlightLevel")||void 0;var r=this.ini.getString("Locomotor"),e=this.type===ObjectType.Building?LocomotorType.Statue:LocomotorType.Chrono;if(r?(t=locomotorTypesByClsId.get(r))?this.locomotor=t:(console.warn(`Object rules "${this.name}" has invalid Locomotor "${r}"`),this.locomotor=e):this.locomotor=e,this.locomotor!==LocomotorType.Statue){let e=defaultSpeedsByLocomotor.get(this.locomotor);void 0===e&&(this.type===ObjectType.Aircraft||this.consideredAircraft?e=SpeedType.Winged:this.type===ObjectType.Vehicle?e=this.crusher?SpeedType.Track:SpeedType.Wheel:this.type===ObjectType.Infantry&&(e=SpeedType.Foot)),this.speedType=this.ini.getEnum("SpeedType",SpeedType,e,!0)}e=[LocomotorType.Ship,LocomotorType.Vehicle,LocomotorType.Chrono].includes(this.locomotor)?65:100;this.speed=ObjectRules.iniSpeedToLeptonsPerTick(this.ini.getNumber("Speed"),e),this.movementZone=this.ini.getEnum("MovementZone",MovementZone,MovementZone.Normal),this.fearless=this.ini.getBool("Fearless"),this.deployer=this.ini.getBool("Deployer"),this.deployFire=this.ini.getBool("DeployFire"),this.deployFireWeapon=this.ini.getNumber("DeployFireWeapon",WeaponType.Secondary),this.undeployDelay=this.ini.getNumber("UndeployDelay"),this.fraidycat=this.ini.getBool("Fraidycat",!1),this.isHuman=!this.ini.getBool("NotHuman"),this.organic=this.type===ObjectType.Infantry||this.ini.getBool("Organic"),this.occupier=this.ini.getBool("Occupier"),this.engineer=this.ini.getBool("Engineer"),this.ivan=this.ini.getBool("Ivan"),this.civilian=this.ini.getBool("Civilian"),this.agent=this.ini.getBool("Agent"),this.infiltrate=this.ini.getBool("Infiltrate"),this.threatPosed=this.ini.getNumber("ThreatPosed"),this.specialThreatValue=this.ini.getNumber("SpecialThreatValue"),this.canPassiveAquire=this.ini.getBool("CanPassiveAquire",!0),this.canRetaliate=this.ini.getBool("CanRetaliate",!0),this.preventAttackMove=this.ini.getBool("PreventAttackMove"),this.opportunityFire=this.ini.getBool("OpportunityFire"),this.distributedFire=this.ini.getBool("DistributedFire"),this.radialFireSegments=this.ini.getNumber("RadialFireSegments"),this.attackCursorOnFriendlies=this.ini.getBool("AttackCursorOnFriendlies"),this.bombable=this.ini.getBool("Bombable",!0),this.trainable=this.ini.getBool("Trainable",this.type!==ObjectType.Building),this.crewed=this.ini.getBool("Crewed"),this.parasiteable=this.ini.getBool("Parasiteable",this.type!==ObjectType.Building),this.suppressionThreshold=this.ini.getNumber("SuppressionThreshold"),this.reselectIfLimboed=this.ini.getBool("ReselectIfLimboed"),this.rejoinTeamIfLimboed=this.ini.getBool("RejoinTeamIfLimboed"),this.weight=this.ini.getNumber("Weight"),this.accelerates=this.ini.getBool("Accelerates",!0),this.accelerationFactor=this.ini.getNumber("AccelerationFactor",.03),this.teleporter=this.ini.getBool("Teleporter"),this.canDisguise=this.ini.getBool("CanDisguise"),this.disguiseWhenStill=this.ini.getBool("DisguiseWhenStill"),this.permaDisguise=this.ini.getBool("PermaDisguise"),this.detectDisguise=this.ini.getBool("DetectDisguise"),this.detectDisguiseRange=this.ini.getNumber("DetectDisguiseRange"),this.cloakable=this.ini.getBool("Cloakable"),this.sensors=this.ini.getBool("Sensors"),this.sensorArray=this.ini.getBool("SensorArray"),this.sensorsSight=this.ini.getNumber("SensorsSight"),this.burstDelay=this.parseBurstDelay(),this.vhpScan=this.ini.getEnum("VHPScan",VhpScan,VhpScan.None,!0),this.pip=this.ini.getEnum("Pip",PipColor,PipColor.Green,!0),this.passengers=this.ini.getNumber("Passengers"),this.gunner=this.ini.getBool("Gunner"),this.ammo=this.ini.getNumber("Ammo",-1),this.initialAmmo=this.ini.getNumber("InitialAmmo",-1),this.manualReload=this.ini.getBool("ManualReload",this.type===ObjectType.Aircraft),this.storage=this.ini.getNumber("Storage"),this.spawned=this.ini.getBool("Spawned"),this.spawns=this.ini.getString("Spawns"),this.spawnsNumber=this.ini.getNumber("SpawnsNumber"),this.spawnRegenRate=this.ini.getNumber("SpawnRegenRate"),this.spawnReloadRate=this.ini.getNumber("SpawnReloadRate"),this.missileSpawn=this.ini.getBool("MissileSpawn"),this.size=this.ini.getNumber("Size",1),this.sizeLimit=this.ini.getNumber("SizeLimit"),this.sight=Math.min(TechnoRules.MAX_SIGHT,this.needsEngineer?6:this.ini.getNumber("Sight",1)),this.spySat=this.ini.getBool("SpySat"),this.gapGenerator=this.ini.getBool("GapGenerator"),this.gapRadiusInCells=this.ini.getNumber("GapRadiusInCells"),this.psychicDetectionRadius=this.ini.getNumber("PsychicDetectionRadius"),this.hasRadialIndicator=this.ini.getBool("HasRadialIndicator"),this.harvester=this.ini.getBool("Harvester"),this.unloadingClass=this.ini.getString("UnloadingClass"),this.dock=this.ini.getArray("Dock"),this.radar=this.ini.getBool("Radar"),this.radarInvisible=this.ini.getBool("RadarInvisible"),this.revealToAll=this.ini.getBool("RevealToAll"),this.selectable=!(this.type===ObjectType.Aircraft&&!i)&&this.ini.getBool("Selectable",!0),this.isSelectableCombatant=this.ini.getBool("IsSelectableCombatant"),this.invisibleInGame=this.ini.getBool("InvisibleInGame"),this.moveToShroud=this.ini.getBool("MoveToShroud",this.type!==ObjectType.Aircraft),this.leadershipRating=this.ini.getNumber("LeadershipRating",5),this.unnatural=this.ini.getBool("Unnatural"),this.natural=this.ini.getBool("Natural"),this.buildTimeMultiplier=this.ini.getFixed("BuildTimeMultiplier",1),this.allowedToStartInMultiplayer=this.ini.getBool("AllowedToStartInMultiplayer",!0),this.rot=ObjectRules.iniRotToDegsPerTick(this.ini.getNumber("ROT",0)),this.jumpjetAccel=this.ini.getNumber("JumpJetAccel",2),this.jumpjetClimb=this.ini.getNumber("JumpjetClimb",5),this.jumpjetCrash=this.ini.getNumber("JumpjetCrash",5),this.jumpjetDeviation=this.ini.getNumber("JumpjetDeviation",40),this.jumpjetHeight=this.ini.getNumber("JumpjetHeight",500),this.jumpjetNoWobbles=this.ini.getBool("JumpjetNoWobbles"),this.jumpjetSpeed=this.ini.getNumber("JumpjetSpeed",14),this.jumpjetTurnRate=ObjectRules.iniRotToDegsPerTick(this.ini.getNumber("JumpJetTurnRate",4)),this.jumpjetWobbles=this.ini.getNumber("JumpjetWobbles",.15),this.pitchSpeed=this.ini.getNumber("PitchSpeed",.25),this.pitchAngle=1<=this.pitchSpeed?0:20,this.damageParticleSystems=this.ini.getArray("DamageParticleSystems");i=this.ini.getNumberArray("DamageSmokeOffset",void 0,[0,0,0]);this.damageSmokeOffset=new Vector3_Vector3(i[0],i[2]/Math.SQRT2,i[1]),this.minDebris=this.ini.getNumber("MinDebris"),this.maxDebris=this.ini.getNumber("MaxDebris"),this.debrisTypes=this.ini.getArray("DebrisTypes"),this.debrisAnims=this.ini.getArray("DebrisAnims"),this.isLightpost="GALITE"===this.imageName,this.lightVisibility=this.ini.getNumber("LightVisibility",5e3),this.lightIntensity=this.ini.getNumber("LightIntensity"),this.lightRedTint=this.ini.getNumber("LightRedTint",1),this.lightGreenTint=this.ini.getNumber("LightGreenTint",1),this.lightBlueTint=this.ini.getNumber("LightBlueTint",1),this.ambientSound=this.ini.getString("AmbientSound")||void 0,this.createSound=this.ini.getString("CreateSound")||void 0,this.deploySound=this.ini.getString("DeploySound")||void 0,this.undeploySound=this.ini.getString("UndeploySound")||void 0,this.voiceSelect=this.ini.getString("VoiceSelect")||void 0,this.voiceMove=this.ini.getString("VoiceMove")||void 0,this.voiceAttack=this.ini.getString("VoiceAttack")||void 0,this.voiceFeedback=this.ini.getString("VoiceFeedback")||void 0,this.voiceSpecialAttack=this.ini.getString("VoiceSpecialAttack")||void 0,this.voiceEnter=this.ini.getString("VoiceEnter")||void 0,this.voiceCapture=this.ini.getString("VoiceCapture")||void 0,this.voiceCrashing=this.ini.getString("VoiceCrashing")||void 0,this.crashingSound=this.ini.getString("CrashingSound")||void 0,this.impactLandSound=this.ini.getString("ImpactLandSound")||void 0,this.auxSound1=this.ini.getString("AuxSound1")||void 0,this.auxSound2=this.ini.getString("AuxSound2")||void 0,this.dieSound=this.ini.getString("DieSound")||void 0,this.moveSound=this.ini.getString("MoveSound")||void 0,this.enterWaterSound=this.ini.getString("EnterWaterSound")||void 0,this.leaveWaterSound=this.ini.getString("LeaveWaterSound")||void 0,this.turretRotateSound=this.ini.getString("TurretRotateSound")||void 0,this.workingSound=this.ini.getString("WorkingSound")||void 0,this.notWorkingSound=this.ini.getString("NotWorkingSound")||void 0,this.chronoInSound=this.ini.getString("ChronoInSound")||void 0,this.chronoOutSound=this.ini.getString("ChronoOutSound")||void 0,this.enterTransportSound=this.ini.getString("EnterTransportSound")||void 0,this.leaveTransportSound=this.ini.getString("LeaveTransportSound")||void 0}parseWeaponName(e){return e&&"none"!==e.toLowerCase()?e:void 0}parseTurretIndexes(){let i=new Map;return this.ini.getBool("Gunner")&&this.ini.entries.forEach((e,t)=>{t=t.match(/^(.*)TurretWeapon$/i);t&&(t=t[1]+"TurretIndex",this.ini.has(t)&&i.set(Number(e),this.ini.getNumber(t)))}),i}parseBurstDelay(){let t=[];for(let e=0;e<4;++e)t.push(this.ini.has("BurstDelay"+e)?this.ini.getNumber("BurstDelay"+e):void 0);return t}hasOwner(e){return!!this.owner.length&&-1!==this.owner.indexOf(e.name)}isAvailableTo(e){return(!this.requiredHouses.length||-1!==this.requiredHouses.indexOf(e.name))&&-1===this.forbiddenHouses.indexOf(e.name)}getWeaponAtIndex(e){return this.parseWeaponName(this.ini.getString("Weapon"+(e+1)))}getEliteWeaponAtIndex(e){return this.parseWeaponName(this.ini.getString("EliteWeapon"+(e+1)))}}TechnoRules.MAX_SIGHT=11;class OverlayRules extends ObjectRules{parse(){super.parse(),this.armor=this.ini.getEnum("Armor",ArmorType,ArmorType.None,!0),this.crate=this.ini.getBool("Crate");var e=this.ini.getBool("IsARock");this.isARock=e,this.isRubble=this.ini.getBool("IsRubble"),this.isVeinholeMonster=this.ini.getBool("IsVeinholeMonster"),this.isVeins=this.ini.getBool("IsVeins"),this.land=this.ini.getEnum("Land",LandType,LandType.Clear),this.noUseTileLandType=!!this.ini.getString("NoUseTileLandType"),this.strength=this.ini.getNumber("Strength"),this.tiberium=this.ini.getBool("Tiberium");var t=this.ini.getBool("Wall");this.wall=t,this.radarInvisible=this.ini.getBool("RadarInvisible",!t&&!e)}}function testOccupationBit(e,t){switch(e){case 0:case 1:return!0;case 2:return 0!=(t&OccupationBits.Right);case 3:return 0!=(t&OccupationBits.Left);case 4:return 0!=(t&OccupationBits.Bottom);default:throw new Error('Invalid subCell "'+e)}}!function(e){e[e.All=7]="All",e[e.Right=1]="Right",e[e.Left=2]="Left",e[e.Bottom=4]="Bottom"}(OccupationBits=OccupationBits||{});class TerrainRules extends ObjectRules{parse(){super.parse(),this.animationRate=this.ini.getNumber("AnimationRate"),this.animationProbability=this.ini.getNumber("AnimationProbability"),this.gate=this.ini.getBool("Gate"),this.immune=this.ini.getBool("Immune"),this.isAnimated=this.ini.getBool("IsAnimated"),this.snowOccupationBits=this.normalizeOccupationBits(this.ini.getNumber("SnowOccupationBits",OccupationBits.All)),this.spawnsTiberium=this.ini.getBool("SpawnsTiberium"),this.strength=this.ini.getNumber("Strength"),this.radarInvisible=this.ini.getBool("RadarInvisible"),this.temperateOccupationBits=this.normalizeOccupationBits(this.ini.getNumber("TemperateOccupationBits",OccupationBits.All))}normalizeOccupationBits(e){return(e+8*Math.abs(Math.floor(e/8)))%8}getOccupationBits(e){return e!==TheaterType.Snow?this.temperateOccupationBits:this.snowOccupationBits}getOccupiedSubCells(e){var t,i=this.getOccupationBits(e),e=[0,1,2,3,4];if(i===OccupationBits.All)return e;let r=[];for(t of e)testOccupationBit(t,i)&&r.push(t);return r}}class SmudgeRules extends ObjectRules{parse(){super.parse(),this.burn=this.ini.getBool("Burn"),this.crater=this.ini.getBool("Crater"),this.width=this.ini.getNumber("Width",1),this.height=this.ini.getNumber("Height",1)}}class DebrisRules extends ObjectRules{parse(){super.parse(),this.damage=this.ini.getNumber("Damage"),this.damageRadius=this.ini.getNumber("DamageRadius"),this.duration=this.ini.getNumber("Duration"),this.elasticity=clamp(this.ini.getNumber("Elasticity",.75),0,1),this.expireAnim=this.ini.getString("ExpireAnim")||void 0,this.minAngularVelocity=this.ini.getNumber("MinAngularVelocity"),this.maxAngularVelocity=this.ini.getNumber("MaxAngularVelocity"),this.maxXYVel=this.ini.getNumber("MaxXYVel"),this.minZVel=this.ini.getNumber("MinZVel"),this.maxZVel=this.ini.getNumber("MaxZVel"),this.shareTurretData=this.ini.getBool("ShareTurretData"),this.shareBodyData=this.ini.getBool("ShareBodyData"),this.shareBarrelData=this.ini.getBool("ShareBarrelData"),this.shareSource=this.ini.getString("ShareSource")||void 0,this.trailerAnim=this.ini.getString("TrailerAnim")||void 0,this.trailerSeparation=this.ini.getNumber("TrailerSeperation"),this.warhead=this.ini.getString("Warhead")||void 0}}class ObjectRulesFactory{create(e,t,i,r){switch(e){case ObjectType.Aircraft:case ObjectType.Building:case ObjectType.Infantry:case ObjectType.Vehicle:return new TechnoRules(e,t,r,i);case ObjectType.Overlay:return new OverlayRules(e,t,r);case ObjectType.Terrain:return new TerrainRules(e,t,r);case ObjectType.Smudge:return new SmudgeRules(e,t,r);case ObjectType.VoxelAnim:return new DebrisRules(e,t,r);default:return new ObjectRules(e,t,r)}}}class CombatDamageRules{readIni(e){this.ballisticScatter=e.getNumber("BallisticScatter"),this.bridgeStrength=e.getNumber("BridgeStrength"),this.c4Delay=e.getNumber("C4Delay"),this.c4Warhead=e.getString("C4Warhead"),this.deathWeapon=e.getString("DeathWeapon"),this.dMislEliteWarhead=e.getString("DMislEliteWarhead"),this.dMislWarhead=e.getString("DMislWarhead"),this.flameDamage=e.getString("FlameDamage"),this.ironCurtainDuration=e.getNumber("IronCurtainDuration"),this.ivanDamage=e.getNumber("IvanDamage"),this.ivanIconFlickerRate=e.getNumber("IvanIconFlickerRate"),this.ivanTimedDelay=e.getNumber("IvanTimedDelay"),this.ivanWarhead=e.getString("IvanWarhead"),this.splashList=e.getArray("SplashList"),this.v3EliteWarhead=e.getString("V3EliteWarhead"),this.v3Warhead=e.getString("V3Warhead")}}class TiberiumRules{constructor(e){this.type=e}readIni(e){return this.value=e.getNumber("Value"),this}}class AiRules{readIni(e){this.buildPower=e.getArray("BuildPower"),this.buildRefinery=e.getArray("BuildRefinery"),this.buildTech=e.getArray("BuildTech"),this.tiberiumFarScan=e.getNumber("TiberiumFarScan",50),this.tiberiumNearScan=e.getNumber("TiberiumNearScan",5)}}class ElevationModelRules{readIni(e){return this.increment=e.getNumber("ElevationIncrement"),this.incrementBonus=e.getNumber("ElevationIncrementBonus",1),this.bonusCap=e.getNumber("ElevationBonusCap"),this}getBonus(e,t){return e<=t?0:Math.min(this.bonusCap,Math.floor((e-t)/this.increment))*this.incrementBonus}}class RadiationRules{readIni(e){this.radDurationMultiple=e.getNumber("RadDurationMultiple"),this.radApplicationDelay=e.getNumber("RadApplicationDelay"),this.radLevelMax=e.getNumber("RadLevelMax"),this.radLevelDelay=e.getNumber("RadLevelDelay"),this.radLightDelay=e.getNumber("RadLightDelay"),this.radLevelFactor=e.getNumber("RadLevelFactor"),this.radLightFactor=e.getNumber("RadLightFactor"),this.radTintFactor=e.getNumber("RadTintFactor"),this.radColor=e.getNumberArray("RadColor"),this.radSiteWarhead=e.getString("RadSiteWarhead")}}!function(e){e[e.MultiMissile=0]="MultiMissile",e[e.IronCurtain=1]="IronCurtain",e[e.LightningStorm=2]="LightningStorm",e[e.ChronoSphere=3]="ChronoSphere",e[e.ChronoWarp=4]="ChronoWarp",e[e.ParaDrop=5]="ParaDrop",e[e.AmerParaDrop=6]="AmerParaDrop"}(SuperWeaponType=SuperWeaponType||{});class SuperWeaponRules{constructor(e){this.index=e}readIni(e){return this.disableableFromShell=e.getBool("DisableableFromShell"),this.isPowered=e.getBool("IsPowered",!0),this.name=e.name,this.preClick=e.getBool("PreClick"),this.preDependent=e.getEnum("PreDependent",SuperWeaponType,void 0),this.postClick=e.getBool("PostClick"),this.rechargeTime=e.getNumber("RechargeTime",5),this.showTimer=e.getBool("ShowTimer"),this.sidebarImage=e.getString("SidebarImage").toLowerCase(),this.type=e.getEnum("Type",SuperWeaponType,void 0),this.uiName=e.getString("UIName"),this.weaponType=e.getString("WeaponType")||void 0,this}}class CrateRules{readIni(e){this.crateMaximum=e.getNumber("CrateMaximum"),this.crateMinimum=e.getNumber("CrateMinimum"),this.crateRadius=e.getNumber("CrateRadius"),this.crateRegen=e.getNumber("CrateRegen");let t=e.getString("UnitCrateType");return this.unitCrateType="none"!==t.toLowerCase()?t:void 0,this.healCrateSound=e.getString("HealCrateSound"),this.crateImg=e.getString("CrateImg"),this.waterCrateImg=e.getString("WaterCrateImg"),this.freeMCV=e.getBool("FreeMCV"),this}}!function(e){e[e.Cheer=0]="Cheer",e[e.UnitDeployUndeploy=1]="UnitDeployUndeploy",e[e.WeaponFire=2]="WeaponFire",e[e.ObjectDestroy=3]="ObjectDestroy",e[e.ObjectSpawn=4]="ObjectSpawn",e[e.ObjectUnspawn=5]="ObjectUnspawn",e[e.ObjectMorph=6]="ObjectMorph",e[e.ObjectLiftOff=7]="ObjectLiftOff",e[e.ObjectLand=8]="ObjectLand",e[e.ObjectCrashing=9]="ObjectCrashing",e[e.ObjectDisguiseChange=10]="ObjectDisguiseChange",e[e.ObjectCloakChange=11]="ObjectCloakChange",e[e.ObjectAttacked=12]="ObjectAttacked",e[e.ShipSubmergeChange=13]="ShipSubmergeChange",e[e.BridgeRepair=14]="BridgeRepair",e[e.BuildStatusChange=15]="BuildStatusChange",e[e.BuildingPlace=16]="BuildingPlace",e[e.BuildingFailedPlace=17]="BuildingFailedPlace",e[e.ObjectSell=18]="ObjectSell",e[e.BuildingRepairFull=19]="BuildingRepairFull",e[e.BuildingCapture=20]="BuildingCapture",e[e.BuildingInfiltration=21]="BuildingInfiltration",e[e.BuildingGarrison=22]="BuildingGarrison",e[e.BuildingEvacuate=23]="BuildingEvacuate",e[e.BuildingRepairStart=24]="BuildingRepairStart",e[e.UnitRepairStart=25]="UnitRepairStart",e[e.UnitRepairFinish=26]="UnitRepairFinish",e[e.UnitRecycle=27]="UnitRecycle",e[e.InflictDamage=28]="InflictDamage",e[e.HealthChange=29]="HealthChange",e[e.WarheadDetonate=30]="WarheadDetonate",e[e.PlayerDefeated=31]="PlayerDefeated",e[e.PlayerResigned=32]="PlayerResigned",e[e.PlayerDropped=33]="PlayerDropped",e[e.DeployNotAllowed=34]="DeployNotAllowed",e[e.PowerChange=35]="PowerChange",e[e.PowerLow=36]="PowerLow",e[e.PowerRestore=37]="PowerRestore",e[e.RadarOnOff=38]="RadarOnOff",e[e.ObjectOwnerChange=39]="ObjectOwnerChange",e[e.RadarEvent=40]="RadarEvent",e[e.InsufficientFunds=41]="InsufficientFunds",e[e.RallyPointChange=42]="RallyPointChange",e[e.PrimaryFactoryChange=43]="PrimaryFactoryChange",e[e.FactoryProduceUnit=44]="FactoryProduceUnit",e[e.ObjectTeleport=45]="ObjectTeleport",e[e.AllianceChange=46]="AllianceChange",e[e.UnitPromote=47]="UnitPromote",e[e.EnterTransport=48]="EnterTransport",e[e.LeaveTransport=49]="LeaveTransport",e[e.EnterObject=50]="EnterObject",e[e.EnterTile=51]="EnterTile",e[e.SuperWeaponReady=52]="SuperWeaponReady",e[e.SuperWeaponActivate=53]="SuperWeaponActivate",e[e.LightningStormManifest=54]="LightningStormManifest",e[e.LightningStormCloud=55]="LightningStormCloud",e[e.CratePickup=56]="CratePickup",e[e.PingLocation=57]="PingLocation",e[e.StalemateDetect=58]="StalemateDetect",e[e.TriggerSoundFx=59]="TriggerSoundFx",e[e.TriggerStopSoundFx=60]="TriggerStopSoundFx",e[e.TriggerEva=61]="TriggerEva",e[e.TriggerAnim=62]="TriggerAnim",e[e.TriggerText=63]="TriggerText",e[e.TimerExpire=64]="TimerExpire"}(EventType=EventType||{});class CratePickupEvent{constructor(e,t,i,r){this.target=e,this.player=t,this.source=i,this.tile=r,this.type=EventType.CratePickup}}function getZoneType(e){return[LandType.Water,LandType.Beach].includes(e)?ZoneType.Water:ZoneType.Ground}!function(e){e[e.Ground=0]="Ground",e[e.Air=1]="Air",e[e.Water=2]="Water"}(ZoneType=ZoneType||{});const isGameObject=e=>void 0!==e.position,isVector3=e=>void 0!==e.addScalar;class RangeHelper{constructor(e){this.tileOccupation=e}isInWeaponRange(e,t,i,r,s){var a=s??e;if(i.rules.limboLaunch&&2<Math.abs((isGameObject(a)?a.position.tileElevation+a.tile.z:a.z)-(isGameObject(t)?t.position.tileElevation+t.tile.z:t.z)))return!1;var{minRange:s,range:r}=this.computeWeaponRangeVsTarget(a,t,i,r);return i.rules.cellRangefinding?this.isInTileRange(a,t,s,r):e.isUnit()&&e.rules.movementZone===MovementZone.Fly?this.isInRange2(a,t,s,r):this.isInRange3(a,t,s,r)}computeWeaponRangeVsTarget(e,t,i,r){let s=0;var a,n;return isGameObject(t)&&t.isBuilding()&&!i.projectileRules.arcing&&!i.projectileRules.vertical&&(n=t.getFoundation(),i.warhead.rules.ivanBomb&&2<n.width+n.height||(s+=(n.width+n.height)/4)),!i.projectileRules.subjectToElevation||i.projectileRules.arcing&&!isGameObject(t)||(a=isGameObject(e)?e.tile.z+e.tileElevation:e.z,(n=isGameObject(t)?t.tile.z+t.tileElevation:t.z)<a&&(s+=r.elevationModel.getBonus(a,n))),i.projectileRules.isAntiAir&&isGameObject(e)&&e.isTechno()&&isGameObject(t)&&t.isUnit()&&t.zone===ZoneType.Air&&(s+=e.rules.airRangeBonus),{minRange:i.minRange,range:i.range+s}}isInRange(e,t,i,r,s=!1){return s?this.isInTileRange(e,t,i,r):e.isUnit()&&e.rules.movementZone===MovementZone.Fly?this.isInRange2(e,t,i,r):this.isInRange3(e,t,i,r)}isInRange3(e,t,i,r){return isBetween(this.distance3(e,t)/Coords.LEPTONS_PER_TILE,i,r)}isInRange2(e,t,i,r){return isBetween(this.distance2(e,t)/Coords.LEPTONS_PER_TILE,i,r)}distance3(e,t){let i=isGameObject(e)?e.position.worldPosition:isVector3(e)?e:Coords.tile3dToWorld(e.rx+.5,e.ry+.5,e.z);t=isGameObject(t)?t.position.worldPosition:isVector3(t)?t:Coords.tile3dToWorld(t.rx+.5,t.ry+.5,t.z);return i.distanceTo(t)}distance2(e,t){let i=isGameObject(e)?new Vector2(e.position.worldPosition.x,e.position.worldPosition.z):isVector3(e)?new Vector2(e.x,e.z):new Vector2(e.rx+.5,e.ry+.5).multiplyScalar(Coords.LEPTONS_PER_TILE);t=isGameObject(t)?new Vector2(t.position.worldPosition.x,t.position.worldPosition.z):isVector3(t)?new Vector2(t.x,t.z):new Vector2(t.rx+.5,t.ry+.5).multiplyScalar(Coords.LEPTONS_PER_TILE);return i.distanceTo(t)}isInTileRange(e,t,i,r){let s;var a;return s=!Array.isArray(e)&&isGameObject(t)&&t.isUnit()?(a=isGameObject(e)?e.tile:e,new Vector2(a.rx+.5,a.ry+.5).distanceTo(t.position.getMapPosition().multiplyScalar(1/Coords.LEPTONS_PER_TILE))):this.tileDistance(e,t),isBetween(s,i,r)}tileDistance(e,t){var i,e=isGameObject(e)?this.tileOccupation.calculateTilesForGameObject(e.tile,e):Array.isArray(e)?e:[e],r=isGameObject(t)?this.tileOccupation.calculateTilesForGameObject(t.tile,t):Array.isArray(t)?t:[t];let s=new Vector2,a=new Vector2,n=Number.POSITIVE_INFINITY;for(i of e)for(var o of r){s.set(i.rx,i.ry),a.set(o.rx,o.ry);o=s.distanceTo(a);o<=n&&(n=o)}return n}}const isHumanPlayerInfo=e=>"name"in e;!function(e){e[e.Brutal=0]="Brutal",e[e.Medium=1]="Medium",e[e.Easy=2]="Easy"}(AiDifficulty=AiDifficulty||{});const RANDOM_COUNTRY_ID=-2,RANDOM_COLOR_ID=-2,RANDOM_START_POS=-2,NO_TEAM_ID=-2,OBS_COUNTRY_ID=-3,OBS_COLOR_ID=-2,RANDOM_COUNTRY_NAME="Random",OBS_COUNTRY_NAME="Observer",aiUiNames=(new Map).set(AiDifficulty.Easy,"GUI:AIDummy").set(AiDifficulty.Medium,"GUI:AIEasyBeta"),aiUiTooltips=new Map,RANDOM_COUNTRY_UI_NAME="GUI:RandomEx",RANDOM_COUNTRY_UI_TOOLTIP="STT:PlayerSideRandom",OBS_COUNTRY_UI_NAME="GUI:Observer",OBS_COUNTRY_UI_TOOLTIP="STT:PlayerSideObserver",RANDOM_COLOR_NAME="";class GameSpeed{static computeGameSpeed(e){let t;return t=6===e?60:5===e?45:60/(6-e),t/GameSpeed.BASE_TICKS_PER_SECOND}}GameSpeed.BASE_TICKS_PER_SECOND=15;class RadialTileFinder{constructor(e,t,i,r,s,a,n,o=!0){this.tiles=e,this.mapBounds=t,this.startTile=i,this.foundation=r,this.maxDistance=a,this.predicate=n,this.checkBounds=o,this.distance=s,this.generator=this.generate()}getNextTile(){return this.generator.next().value}*generate(){var r=(e,t)=>{t=this.tiles.getByMapCoords(e,t);if(t&&(!this.checkBounds||this.mapBounds.isWithinBounds(t))&&this.predicate(t))return t};do{var s=this.startTile.rx-this.distance,a=this.startTile.ry-this.distance,n=this.startTile.rx+this.foundation.width-1+this.distance,o=this.startTile.ry+this.foundation.height-1+this.distance;let e,t,i;if(0<this.distance){for(e=n;e>=s;e--)i=r(e,o),i&&(yield i);for(t=o-1;t>=a;t--)i=r(n,t),i&&(yield i);for(e=s;e<n;e++)i=r(e,a),i&&(yield i);for(t=1+a;t<o;t++)i=r(s,t),i&&(yield i)}else this.predicate(this.startTile)&&(yield this.startTile)}while(this.distance++,this.distance<=this.maxDistance)}}!function(e){e[e.Armor=0]="Armor",e[e.Firepower=1]="Firepower",e[e.HealBase=2]="HealBase",e[e.Money=3]="Money",e[e.Reveal=4]="Reveal",e[e.Speed=5]="Speed",e[e.Veteran=6]="Veteran",e[e.Unit=7]="Unit",e[e.Invulnerability=8]="Invulnerability",e[e.IonStorm=9]="IonStorm",e[e.Gas=10]="Gas",e[e.Tiberium=11]="Tiberium",e[e.Pod=12]="Pod",e[e.Cloak=13]="Cloak",e[e.Darkness=14]="Darkness",e[e.Explosion=15]="Explosion",e[e.ICBM=16]="ICBM",e[e.Napalm=17]="Napalm",e[e.Squad=18]="Squad"}(PowerupType=PowerupType||{}),(NotifyTick=NotifyTick||{}).onTick=Symbol(),(NotifyWarpChange=NotifyWarpChange||{}).onChange=Symbol();class SuperWeaponReadyEvent{constructor(e){this.target=e,this.type=EventType.SuperWeaponReady}}!function(e){e[e.Charging=0]="Charging",e[e.Paused=1]="Paused",e[e.Ready=2]="Ready"}(SuperWeaponStatus=SuperWeaponStatus||{});class SuperWeapon{constructor(e,t,i,r=!1){this.name=e,this.rules=t,this.owner=i,this.oneTimeOnly=r,this.status=SuperWeaponStatus.Charging,this.isGift=!1,this.rechargeTicks=60*t.rechargeTime*GameSpeed.BASE_TICKS_PER_SECOND,this.chargeTicks=this.rechargeTicks,r&&(this.status=SuperWeaponStatus.Ready,this.chargeTicks=0)}update(e){0<this.chargeTicks&&this.status!==SuperWeaponStatus.Paused&&(this.chargeTicks--,0===this.chargeTicks&&(this.status=SuperWeaponStatus.Ready,e.events.dispatch(new SuperWeaponReadyEvent(this))))}pauseTimer(){this.status=SuperWeaponStatus.Paused}resumeTimer(){this.status=0<this.chargeTicks?SuperWeaponStatus.Charging:SuperWeaponStatus.Ready}resetTimer(){this.chargeTicks=this.rechargeTicks,this.status===SuperWeaponStatus.Ready&&(this.status=SuperWeaponStatus.Charging)}getTimerSeconds(){return this.chargeTicks/GameSpeed.BASE_TICKS_PER_SECOND}getChargeProgress(){return(this.rechargeTicks-this.chargeTicks)/this.rechargeTicks}}!function(e){e[e.NotStarted=0]="NotStarted",e[e.Running=1]="Running",e[e.Finished=2]="Finished"}(EffectStatus=EffectStatus||{});class SuperWeaponEffect{constructor(e,t,i){this.type=e,this.owner=t,this.tile=i,this.status=EffectStatus.NotStarted}onStart(e){}onTick(e){return!0}}!function(e){e.onPowerLow=Symbol(),e.onPowerRestore=Symbol(),e.onPowerChange=Symbol()}(NotifyPower=NotifyPower||{}),(NotifySuperWeaponActivate=NotifySuperWeaponActivate||{}).onActivate=Symbol();class SuperWeaponActivateEvent{constructor(e,t,i,r,s){this.target=e,this.owner=t,this.atTile=i,this.atTile2=r,this.noSfxWarning=s,this.type=EventType.SuperWeaponActivate}}!function(e){e[e.None=0]="None",e[e.Guard=1]="Guard",e[e.Prone=2]="Prone",e[e.Deployed=3]="Deployed",e[e.Paradrop=4]="Paradrop",e[e.Cheer=5]="Cheer"}(StanceType=StanceType||{}),function(e){e[e.NotStarted=0]="NotStarted",e[e.Running=1]="Running",e[e.Finished=2]="Finished",e[e.Cancelling=3]="Cancelling",e[e.Cancelled=4]="Cancelled"}(TaskStatus=TaskStatus||{});class Task{constructor(){this.status=TaskStatus.NotStarted,this.children=[],this.cancellable=!0,this.useChildTargetLines=!1,this.blocking=!0,this.waitingForChildrenToFinish=!1,this.preventOpportunityFire=!0,this.preventLanding=!0,this.isAttackMove=!1}isRunning(){return this.status===TaskStatus.Running}isCancelling(){return this.status===TaskStatus.Cancelling}setCancellable(e){return this.cancellable=e,this}setBlocking(e){return this.blocking=e,this}onStart(e){}onEnd(e){}cancel(){if(this.cancellable)if(this.status===TaskStatus.Running)this.status=TaskStatus.Cancelling,this.children.length&&this.children.forEach(e=>e.cancel());else if(this.status===TaskStatus.NotStarted&&(this.status=TaskStatus.Cancelled,this.children.length))throw new Error("Should't have any children before starting a task")}getTargetLinesConfig(e){}}function findReverse(t,i){for(let e=t.length-1;0<=e;e--)if(i(t[e],e,t))return t[e]}function findIndexReverse(t,i){for(let e=t.length-1;0<=e;e--)if(i(t[e],e,t))return e;return-1}function equals(i,r){if(i.length!==r.length)return!1;for(let e=0,t=i.length;e<t;e++)if(i[e]!==r[e])return!1;return!0}class WaitTicksTask extends Task{constructor(e){super(),this.ticks=e}onTick(){return!!this.isCancelling()||!(0<this.ticks--)}}class MovePositionHelper{constructor(e){this.map=e}findPositions(e,r,s,a){let n=new Map,t=this.clusterObjects(e);if(!t.length)throw new Error("We should have found at least one cluster");let i=t.reduce((e,t)=>t.objects.size>e.objects.size?t:e,t[0]);t.splice(t.indexOf(i),1);let o=[],l=this.findCenterTile([...i.objects]);i.objects.forEach(t=>{var i=this.map.tiles.getByMapCoords(r.rx+t.tile.rx-l.rx,r.ry+t.tile.ry-l.ry),e=i?.onBridgeLandType?this.map.tileOccupation.getBridgeOnTile(i):void 0;if(!this.shouldStackObject(t)&&i&&this.map.mapBounds.isWithinBounds(i)&&this.tileHasRoom(i,t,n.get(i))&&(t.rules.movementZone===MovementZone.Fly?t.rules.airportBound||a&&t.rules.balloonHover&&!t.rules.hoverAttack||this.map.terrain.getPassableSpeed(i,SpeedType.Amphibious,!1,!!e):this.isEligibleTile(i,e,s,r))){let e=n.get(i);void 0===e&&(e=[],n.set(i,e)),e.push(t)}else o.push(t)}),t.forEach(e=>o.push(...e.objects));let h=new RadialTileFinder(this.map.tiles,this.map.mapBounds,r,{width:1,height:1},0,5,()=>!0),c=h.getNextTile();for(;o.length&&c;){var d=o[0],u=this.map.tileOccupation.getBridgeOnTile(c);if(this.tileHasRoom(c,d,n.get(c))&&(d.rules.movementZone===MovementZone.Fly?d.rules.airportBound||this.map.terrain.getPassableSpeed(c,SpeedType.Amphibious,!1,!!u):this.isEligibleTile(c,u,s,r))){let e=n.get(c);void 0===e&&(e=[],n.set(c,e)),e.push(o.shift())}else c=h.getNextTile()}let p=new Map;if(n.forEach((e,t)=>{e.forEach(e=>p.set(e,t))}),o.forEach(e=>p.set(e,r)),p.size!==e.length)throw new Error("We should have computed a number of positions equal to the number of input objects");return p}shouldStackObject(e){return e.isBuilding()||e.isUnit()&&e.moveTrait.isMoving()&&e.rules.movementZone===MovementZone.Fly&&e.rules.locomotor===LocomotorType.Jumpjet}tileHasRoom(e,t,i){if(t.isBuilding())return!!t.rules.undeploysInto||!this.map.tileOccupation.getGroundObjectsOnTile(e).some(e=>e.isTerrain()||e.isTechno()||e.isOverlay()&&e.wallTrait);if(!i)return!0;if(this.shouldStackObject(t))return i.length<3;if(t.isInfantry()){if(i.find(e=>!e.isInfantry()))return!1;t=t.rules.movementZone===MovementZone.Fly?1:3;return i.filter(e=>e.isInfantry()).length>=t?!1:!0}return!i.length}isEligibleTile(e,t,i,r){return i?.isHighBridge()||t?.isHighBridge()?e.z+(t?.tileElevation??0)===r.z+(i?.tileElevation??0):!(!i&&!t)||Math.abs(e.z-r.z)<2}clusterObjects(e){let s=new Map;e.forEach(e=>{var t=e.tile.rx+"_"+e.tile.ry;s.set(t,[...s.get(t)||[],e])});let t=[],a=new Set(e);for(;a.size;){let e=new Set,r=[];var i=[...a][0].tile;for(s.get(i.rx+"_"+i.ry).forEach(e=>{r.push(e)});r.length;){var n=r.shift();e.add(n),a.delete(n);for(let i=-1;i<=1;i++)for(let t=-1;t<=1;t++)if(i||t){let e=s.get(n.tile.rx+i+"_"+(n.tile.ry+t));e&&e.length&&e.forEach(e=>{a.has(e)&&(a.delete(e),r.push(e))})}}t.push({objects:e})}return t}findCenterTile(e){let t=0,i=0;e.forEach(e=>{t+=e.tile.rx,i+=e.tile.ry}),t=Math.round(t/e.length),i=Math.round(i/e.length);let r=this.map.tiles.getByMapCoords(t,i);if(!r&&(r=e.find(e=>Math.abs(e.tile.rx-t)<=1&&Math.abs(e.tile.ry-i)<=1)?.tile,!r))throw new Error("At least one adjacent object should have been found");return r}}var Matrix4_THREE=__webpack_require__(70);class Matrix4 extends Matrix4_THREE.Matrix4{extractRotation(e){let t=this.elements;var i=e.elements,r=1/_vector3.setFromMatrixColumn(e,0).length(),s=1/_vector3.setFromMatrixColumn(e,1).length(),e=1/_vector3.setFromMatrixColumn(e,2).length();return t[0]=i[0]*r,t[1]=i[1]*r,t[2]=i[2]*r,t[3]=0,t[4]=i[4]*s,t[5]=i[5]*s,t[6]=i[6]*s,t[7]=0,t[8]=i[8]*e,t[9]=i[9]*e,t[10]=i[10]*e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,this}makeRotationFromEuler(e){e&&e.isEuler||console.error("THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.");let t=this.elements;var i,r,s,a,n,o,l,h,c,d,u,p=e.x,g=e.y,m=e.z,y=GameMath.cos(p),T=GameMath.sin(p),f=GameMath.cos(g),v=GameMath.sin(g),p=GameMath.cos(m),g=GameMath.sin(m);return"XYZ"===e.order?(i=y*p,s=y*g,r=T*p,m=T*g,t[0]=f*p,t[4]=-f*g,t[8]=v,t[1]=s+r*v,t[5]=i-m*v,t[9]=-T*f,t[2]=m-i*v,t[6]=r+s*v,t[10]=y*f):"YXZ"===e.order?(a=f*p,i=f*g,r=v*p,s=v*g,t[0]=a+s*T,t[4]=r*T-i,t[8]=y*v,t[1]=y*g,t[5]=y*p,t[9]=-T,t[2]=i*T-r,t[6]=s+a*T,t[10]=y*f):"ZXY"===e.order?(l=f*p,a=f*g,n=v*p,o=v*g,t[0]=l-o*T,t[4]=-y*g,t[8]=n+a*T,t[1]=a+n*T,t[5]=y*p,t[9]=o-l*T,t[2]=-y*v,t[6]=T,t[10]=y*f):"ZYX"===e.order?(n=y*p,o=y*g,h=T*p,l=T*g,t[0]=f*p,t[4]=h*v-o,t[8]=n*v+l,t[1]=f*g,t[5]=l*v+n,t[9]=o*v-h,t[2]=-v,t[6]=T*f,t[10]=y*f):"YZX"===e.order?(d=y*f,h=y*v,c=T*f,u=T*v,t[0]=f*p,t[4]=u-d*g,t[8]=c*g+h,t[1]=g,t[5]=y*p,t[9]=-T*p,t[2]=-v*p,t[6]=h*g+c,t[10]=d-u*g):"XZY"===e.order&&(c=y*f,d=y*v,u=T*f,e=T*v,t[0]=f*p,t[4]=-g,t[8]=v*p,t[1]=c*g+e,t[5]=y*p,t[9]=d*g-u,t[2]=u*g-d,t[6]=T*p,t[10]=e*g+c),t[3]=0,t[7]=0,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,this}lookAt(e,t,i){_x.set(0,0,0),_y.set(0,0,0),_z.set(0,0,0);const r=this.elements;return _z.subVectors(e,t),0===_z.lengthSq()&&(_z.z=1),_z.normalize(),_x.crossVectors(i,_z),0===_x.lengthSq()&&(1===Math.abs(i.z)?_z.x+=1e-4:_z.z+=1e-4,_z.normalize(),_x.crossVectors(i,_z)),_x.normalize(),_y.crossVectors(_z,_x),r[0]=_x.x,r[4]=_y.x,r[8]=_z.x,r[1]=_x.y,r[5]=_y.y,r[9]=_z.y,r[2]=_x.z,r[6]=_y.z,r[10]=_z.z,this}getMaxScaleOnAxis(){var e=this.elements,t=e[0]*e[0]+e[1]*e[1]+e[2]*e[2],i=e[4]*e[4]+e[5]*e[5]+e[6]*e[6],e=e[8]*e[8]+e[9]*e[9]+e[10]*e[10];return GameMath.sqrt(Math.max(t,i,e))}makeRotationX(e){var t=GameMath.cos(e),e=GameMath.sin(e);return this.set(1,0,0,0,0,t,-e,0,0,e,t,0,0,0,0,1),this}makeRotationY(e){var t=GameMath.cos(e),e=GameMath.sin(e);return this.set(t,0,e,0,0,1,0,0,-e,0,t,0,0,0,0,1),this}makeRotationZ(e){var t=GameMath.cos(e),e=GameMath.sin(e);return this.set(t,-e,0,0,e,t,0,0,0,0,1,0,0,0,0,1),this}makeRotationAxis(e,t){var i=GameMath.cos(t),r=GameMath.sin(t),s=1-i,a=e.x,n=e.y,o=e.z,t=s*a,e=s*n;return this.set(t*a+i,t*n-r*o,t*o+r*n,0,t*n+r*o,e*n+i,e*o-r*a,0,t*o-r*n,e*o+r*a,s*o*o+i,0,0,0,0,1),this}decompose(e,t,i){var r=this.elements;let s=_vector3.set(r[0],r[1],r[2]).length();var a=_vector3.set(r[4],r[5],r[6]).length(),n=_vector3.set(r[8],r[9],r[10]).length();this.determinant()<0&&(s=-s),e.x=r[12],e.y=r[13],e.z=r[14],_matrix.copy(this);var o=1/s,e=1/a,r=1/n;return _matrix.elements[0]*=o,_matrix.elements[1]*=o,_matrix.elements[2]*=o,_matrix.elements[4]*=e,_matrix.elements[5]*=e,_matrix.elements[6]*=e,_matrix.elements[8]*=r,_matrix.elements[9]*=r,_matrix.elements[10]*=r,t.setFromRotationMatrix(_matrix),i.x=s,i.y=a,i.z=n,this}}const _vector3=new Vector3_Vector3,_x=new Vector3_Vector3,_y=new Vector3_Vector3,_z=new Vector3_Vector3,_matrix=new Matrix4;var geometry_THREE=__webpack_require__(70);function radToDeg(e){return e*geometry_THREE.Math.RAD2DEG}function degToRad(e){return e*geometry_THREE.Math.DEG2RAD}const zeroVec=new Vector2;function rotateVec2(e,t){t=degToRad(Math.floor(t));return e.rotateAround(zeroVec,t)}function angleDegFromVec2(e){return Math.round(radToDeg(e.angle()))}function angleDegBetweenQuaternions(e,t){t=radToDeg(2*GameMath.acos(Math.abs(clamp(e.dot(t),-1,1))));return Math.round(t)}function angleDegBetweenVec2(e,t){e=angleDegFromVec2(e),t=angleDegFromVec2(t);return Math.min((e-t+360)%360,(t-e+360)%360)}function angleDegBetweenVec3(e,t){return angleDegBetweenQuaternions(quaternionFromVec3(e,_q1),quaternionFromVec3(t,_q2))}function quaternionFromVec3(e,t=new Quaternion){return t.setFromRotationMatrix(_m4.lookAt(e,_zeroVec3,_upVec3))}const _m4=new Matrix4,_zeroVec3=new Vector3_Vector3(0,0,0),_upVec3=new Vector3_Vector3(0,1,0);function rotateVec3Towards(e,t,i){var r=e.length(),s=quaternionFromVec3(t,_q1),t=quaternionFromVec3(e,_q2);rotateTowards(t,s,i),e.set(0,0,1).applyQuaternion(t).setLength(r)}const _q1=new Quaternion,_q2=new Quaternion;function rotateTowards(e,t,i){var r=angleDegBetweenQuaternions(e,t);if(0!==r){r=Math.min(1,i/r);return e.slerp(t,r)}}const BAILOUT_TICKS=200,RETRY_TICKS=5;class MoveAsideTask extends Task{constructor(e,t){super(),this.game=e,this.fromDirection=t,this.resolved=!1,this.chainPushIssued=!1}onEnd(e){e.moveTrait.collisionState=CollisionState.Resolved}onTick(i){if(this.timeoutTicks=void 0===this.timeoutTicks?0:this.timeoutTicks+1,this.timeoutTicks>BAILOUT_TICKS/RETRY_TICKS||this.resolved||this.isCancelling())return!0;let r=this.game.map,t=new MovePositionHelper(r);var s=i.onBridge?r.tileOccupation.getBridgeOnTile(i.tile):void 0;let a,n;for(let e=0;e<360;e+=45)if((0!==e||this.chainPushIssued)&&180!==e){var o=rotateVec2(this.fromDirection.clone(),e).round(),o=r.tiles.getByMapCoords(i.tile.rx+Math.sign(o.x),i.tile.ry+Math.sign(o.y));if(o&&r.mapBounds.isWithinBounds(o)&&(n=r.tileOccupation.getBridgeOnTile(o),i.rules.movementZone===MovementZone.Fly||!r.terrain.findObstacles({tile:o,onBridge:n},i).length&&t.isEligibleTile(o,n,s,i.tile))){a=o;break}}if(a)return this.resolved=!0,i.isInfantry()&&i.deployerTrait&&i.deployerTrait.isDeployed()&&i.deployerTrait.setDeployed(!1),!!i.moveTrait.isDisabled()||(this.children.push(new MoveTask(this.game,a,!!n,{closeEnoughTiles:0,strictCloseEnough:!0})),!1);{if(this.chainPushIssued)return this.children.push(new WaitTicksTask(RETRY_TICKS)),!1;let t=r.tiles.getByMapCoords(i.tile.rx+Math.sign(this.fromDirection.x),i.tile.ry+Math.sign(this.fromDirection.y));if(!t||!r.mapBounds.isWithinBounds(t))return!0;n=r.tileOccupation.getBridgeOnTile(t);let e=r.tileOccupation.getGroundObjectsOnTile(t).filter(e=>e.isUnit()&&e.owner===i.owner&&e.tile===t&&e.onBridge===!!n&&!(e.isInfantry()&&e.stance===StanceType.Paradrop)&&!(e.isAircraft()&&e.missileSpawnTrait));return e.find(e=>e.moveTrait.collisionState===CollisionState.Waiting||e.unitOrderTrait.hasTasks())?(this.children.push(new WaitTicksTask(RETRY_TICKS)),i.moveTrait.collisionState=CollisionState.Waiting,i.moveTrait.moveState=MoveState.PlanMove,!1):(e.forEach(e=>{e.unitOrderTrait.addTask(new MoveAsideTask(this.game,this.fromDirection))}),this.children.push(new WaitTicksTask(1)),i.moveTrait.collisionState=CollisionState.Waiting,i.moveTrait.moveState=MoveState.PlanMove,!(this.chainPushIssued=!0))}}}var logger=__webpack_require__(370);const AppLogger=logger;class ChronoLocomotor{constructor(e){this.game=e,this.ignoresTerrain=!0,this.distanceToWaypoint=new Vector2}onNewWaypoint(e,t){}tick(e,t,i,r){if(r)return{distance:new Vector3_Vector3,done:!0};this.distanceToWaypoint.copy(t).sub(e.position.getMapPosition());r=this.game.rules.general;return r.chronoTrigger&&(r=(t=this.distanceToWaypoint.length())<r.chronoRangeMinimum?r.chronoMinimumDelay:t/r.chronoDistanceFactor,e.warpedOutTrait.setTimed(r,!1,this.game)),{distance:new Vector3_Vector3(this.distanceToWaypoint.x,0,this.distanceToWaypoint.y),done:!0,isTeleport:!0}}}class FacingUtil{static tick(e,t,i){if(e===t)return{facing:e,delta:0};var r=(e-t+360)%360,s=(t-e+360)%360;if(Math.min(r,s)<i)return{facing:t,delta:0};i*=s<=r?1:-1;return{facing:(e+i+360)%360,delta:i}}static fromMapCoords(e){return(-angleDegFromVec2(e)-90+720)%360}static toMapCoords(e){return rotateVec2(new Vector2(1e3,0),FacingUtil.toWorldDeg(e)).round().normalize()}static toWorldDeg(e){return-(e+90)}}class TurnTask extends Task{constructor(e){super(),this.direction=e,this.cancellable=!1}onTick(e){if(e.direction===this.direction)return!(e.spinVelocity=0);var t=e.rules.rot,{facing:i,delta:t}=FacingUtil.tick(e.direction,this.direction,t);return e.direction=i,e.spinVelocity=t,!1}}var LineCurve_THREE=__webpack_require__(70);class LineCurve extends LineCurve_THREE.LineCurve{constructor(e,t){super(e||new Vector2,t||new Vector2)}getPoint(e,t){return super.getPoint(e,t||new Vector2)}}var CurvePath_THREE=__webpack_require__(70);class CurvePath extends CurvePath_THREE.CurvePath{closePath(){let e=this.curves[0].getPoint(0);var t=this.curves[this.curves.length-1].getPoint(1);e.equals(t)||this.curves.push(new LineCurve(t,e))}}var WaypointType,HoverLocomotor_WaypointType,QuadraticBezierCurve_THREE=__webpack_require__(70);class QuadraticBezierCurve extends QuadraticBezierCurve_THREE.QuadraticBezierCurve{constructor(e,t,i){super(e||new Vector2,t||new Vector2,i||new Vector2)}getPoint(e,t){return super.getPoint(e,t||new Vector2)}}!function(e){e[e.None=0]="None",e[e.Start=1]="Start",e[e.Normal=2]="Normal",e[e.End=3]="End",e[e.Single=4]="Single"}(WaypointType=WaypointType||{});class DriveLocomotor{constructor(e){this.game=e,this.hasMomentum=!1,this.moveOnCurve=!1,this.currentSpeed=0,this.distanceTravelled=0,this.carryOverDistance=0,this.currentWaypointType=WaypointType.None}selectNextWaypoint(i,r){if(this.currentWaypointType=this.currentWaypointType&&this.currentWaypointType!==WaypointType.End?WaypointType.Normal:WaypointType.Start,this.initialPosition=i.position.getMapPosition(),this.currentWaypointType!==WaypointType.Start?i.moveTrait.speedPenalty=0:this.currentSpeed=0,1<r.length){var s=r[r.length-1],a=r[r.length-2],e=new Vector2(s.tile.rx-i.tile.rx,s.tile.ry-i.tile.ry),n=Math.abs(angleDegFromVec2(e)-angleDegFromVec2(new Vector2(a.tile.rx-s.tile.rx,a.tile.ry-s.tile.ry)));if(!Math.abs(FacingUtil.fromMapCoords(e)-i.direction)&&0<n&&n<90&&this.hasMomentum){this.moveOnCurve=!0,this.currentWaypointType=2===r.length?this.currentWaypointType===WaypointType.Start?WaypointType.Single:WaypointType.End:WaypointType.Normal;let e=this.initialPosition;i=new Vector2(s.tile.rx+.5,s.tile.ry+.5).multiplyScalar(Coords.LEPTONS_PER_TILE);let t=new Vector2(a.tile.rx+.5,a.tile.ry+.5).multiplyScalar(Coords.LEPTONS_PER_TILE);n=e.clone().lerp(i,.5),s=t.clone().lerp(i,.5);return this.steerCurve=new CurvePath,this.steerCurve.add(new LineCurve(e,n)),this.steerCurve.add(new QuadraticBezierCurve(n,i,s)),this.steerCurve.add(new LineCurve(s,t)),this.lastPosition=e,a}}else this.currentWaypointType=this.currentWaypointType===WaypointType.Start?WaypointType.Single:WaypointType.End;return this.hasMomentum=!0,this.moveOnCurve=!1,r[r.length-1]}onNewWaypoint(e,t,i){let r=(new Vector2).copy(t).sub(this.initialPosition);this.distanceTravelled=0,this.totalDistanceToTravel=this.moveOnCurve?this.steerCurve.getLength():r.length();t=FacingUtil.fromMapCoords(r);if(t!==e.direction&&(this.pointTurretToTarget(e,i),!this.moveOnCurve))return e.moveTrait.velocity.set(0,0,0),[new TurnTask(t)]}tick(i,r,s){this.pointTurretToTarget(i,s);let a=this.currentSpeed;a=i.rules.accelerates?(l=this.distanceTravelled/this.totalDistanceToTravel,this.currentSpeed=this.applyAcceleration(i,a,i.moveTrait.baseSpeed,l)):this.currentSpeed=i.moveTrait.baseSpeed,1<a&&(a=Math.floor(a));let e=this.game.map.terrain.getPassableSpeed(i.tile,i.rules.speedType,i.isInfantry(),i.onBridge,void 0,!0);e?i.moveTrait.lastTileSpeed=e:e=i.moveTrait.lastTileSpeed||1,a*=e,1<a&&(a=Math.floor(a)),this.carryOverDistance&&(a=this.carryOverDistance);var n=i.position.getMapPosition();let o;if(this.moveOnCurve){var s=this.steerCurve.getLength(),l=Math.min(this.distanceTravelled+a,s);this.carryOverDistance=Math.max(0,this.distanceTravelled+a-s),this.distanceTravelled=l;let e=this.steerCurve.getPointAt(this.distanceTravelled/s),t=this.steerCurve.getTangentAt(this.distanceTravelled/s);l=t.clone().setLength(a);i.moveTrait.velocity.set(l.x,0,l.y);var s=i.rules.rot,{facing:l,delta:s}=FacingUtil.tick(i.direction,FacingUtil.fromMapCoords(t),s);i.direction=l,i.spinVelocity=s;s=this.lastPosition;this.lastPosition=e.clone(),o=e.sub(s)}else{let e=(new Vector2).copy(r).sub(n);n=Math.min(e.length(),a);o=e.clone().setLength(n);let t=o.clone();this.carryOverDistance&&t.add(Coords.vecWorldToGround(i.moveTrait.velocity)),i.moveTrait.velocity.set(t.x,0,t.y),this.distanceTravelled+=n,this.carryOverDistance=Math.max(0,a-e.length())}return{distance:new Vector3_Vector3(o.x,0,o.y),done:!o.length()||!!this.carryOverDistance}}pointTurretToTarget(t,i){if(t.turretTrait){t.attackTrait?.currentTarget?.obj&&(i=t.attackTrait.currentTarget.obj.position.getMapPosition());var r=t.position.getMapPosition();let e=(new Vector2).copy(i).sub(r);e.length()&&(r=FacingUtil.fromMapCoords(e),t.turretTrait.desiredFacing=r)}}applyAcceleration(e,t,i,r){if(this.currentWaypointType===WaypointType.Single)return i/2;if(this.currentWaypointType!==WaypointType.End)return Math.min(t+e.rules.accelerationFactor*i,i);return lerp(1,i,1-(r=this.moveOnCurve&&this.currentWaypointType===WaypointType.End?r<=.5?0:2*(r-.5):r))}}class FootLocomotor{constructor(e){this.game=e,this.currentMoveDirection=new Vector2,this.distanceToWaypoint=new Vector2,this.endPauseFrames=0}onNewWaypoint(e,t){this.currentMoveDirection.copy(t).sub(e.position.getMapPosition());t=FacingUtil.fromMapCoords(this.currentMoveDirection);t!==e.direction&&(e.direction=t),this.endPauseFrames=1}onWaypointUpdate(e,t){this.onNewWaypoint(e,t)}tick(e,t,i){let r=e.moveTrait.baseSpeed;r=Math.floor(r),e.stance===StanceType.Prone&&(r*=e.art.crawls?.5:2),e.isPanicked&&(r*=2);let s=this.game.map.terrain.getPassableSpeed(e.tile,e.rules.speedType,e.isInfantry(),e.onBridge,void 0,!0);s?e.moveTrait.lastTileSpeed=s:s=e.moveTrait.lastTileSpeed||1,r*=s,r=Math.floor(r),this.distanceToWaypoint.copy(t).sub(e.position.getMapPosition());let a=this.distanceToWaypoint.clone().setLength(r);(a.length()||t.equals(i))&&e.moveTrait.velocity.set(a.x,0,a.y);i=Math.min(this.distanceToWaypoint.length(),r),e=!i&&0<this.endPauseFrames--;return this.distanceToWaypoint.setLength(i),{distance:new Vector3_Vector3(this.distanceToWaypoint.x,0,this.distanceToWaypoint.y),done:!this.distanceToWaypoint.length()&&!e}}}!function(e){e[e.None=0]="None",e[e.Start=1]="Start",e[e.Normal=2]="Normal",e[e.End=3]="End",e[e.Single=4]="Single"}(HoverLocomotor_WaypointType=HoverLocomotor_WaypointType||{});class HoverLocomotor{constructor(e){this.hoverRules=e,this.currentSpeed=0,this.distanceTravelled=0,this.carryOverDistance=0,this.currentWaypointType=HoverLocomotor_WaypointType.None,this.nextWaypointDir=new Vector2}selectNextWaypoint(e,t){var i;return this.currentWaypointType=this.currentWaypointType&&this.currentWaypointType!==HoverLocomotor_WaypointType.End?HoverLocomotor_WaypointType.Normal:HoverLocomotor_WaypointType.Start,this.initialPosition=e.position.getMapPosition(),this.currentWaypointType===HoverLocomotor_WaypointType.Start&&(this.currentSpeed=0),t.length<=1?(this.currentWaypointType=this.currentWaypointType===HoverLocomotor_WaypointType.Start?HoverLocomotor_WaypointType.Single:HoverLocomotor_WaypointType.End,(i=t[t.length-1])&&this.nextWaypointDir.set(i.tile.rx-e.tile.rx,i.tile.ry-e.tile.ry)):(i=t[t.length-1],e=t[t.length-2],this.nextWaypointDir.set(e.tile.rx-i.tile.rx,e.tile.ry-i.tile.ry)),t[t.length-1]}onNewWaypoint(e,t,i){let r=(new Vector2).copy(t).sub(this.initialPosition);this.distanceTravelled=0,this.totalDistanceToTravel=r.length();t=this.maxSpeed=e.moveTrait.baseSpeed,e=60*this.hoverRules.acceleration*GameSpeed.BASE_TICKS_PER_SECOND;this.acceleration=t/e;e=60*this.hoverRules.brake*GameSpeed.BASE_TICKS_PER_SECOND;this.deceleration=t/e}tick(e,t){var i=e.position.getMapPosition();let r=t.clone().sub(i);t=r.length(),i=this.maxSpeed;this.currentWaypointType===HoverLocomotor_WaypointType.Single?this.currentSpeed=i/2:this.currentWaypointType===HoverLocomotor_WaypointType.End?(s=this.computeBrakeDistance(this.currentSpeed,this.deceleration),this.totalDistanceToTravel-this.distanceTravelled<=s&&(this.currentSpeed=Math.max(1,this.currentSpeed-this.deceleration))):this.currentSpeed=Math.min(this.currentSpeed+this.acceleration,i);var s=FacingUtil.fromMapCoords(r),i=FacingUtil.fromMapCoords(this.nextWaypointDir);let a=s,n=e.rules.rot;this.currentWaypointType===HoverLocomotor_WaypointType.Normal&&s!==i&&(s=(o=angleDegBetweenVec2(this.nextWaypointDir,FacingUtil.toMapCoords(e.direction)))/n,s=Math.max(this.currentSpeed*s,this.totalDistanceToTravel),this.totalDistanceToTravel-this.distanceTravelled<=s&&(a=i,n=o/((this.totalDistanceToTravel-this.distanceTravelled)/this.currentSpeed)));var o=FacingUtil.tick(e.direction,a,n)["facing"];e.direction=o;let l=this.currentSpeed;this.carryOverDistance&&(l=this.carryOverDistance);o=Math.min(l,t);let h=r.clone().setLength(o),c=h.clone();return this.carryOverDistance&&c.add(Coords.vecWorldToGround(e.moveTrait.velocity)),e.moveTrait.velocity.set(c.x,0,c.y),this.distanceTravelled+=o,this.carryOverDistance=Math.max(0,l-t),{distance:new Vector3_Vector3(h.x,0,h.y),done:!h.length()||!!this.carryOverDistance}}computeBrakeDistance(e,t){var i=e/t;return Math.max(0,e*i-t*i*i/2)}}class TargetUtil{static computeInterceptPoint(e,t,i,r){let s=e.clone().sub(i);var a=r.length(),e=t*t-a*a,t=2*s.dot(r),a=-s.dot(s);if(t*t-4*e*a<0)return new Vector3_Vector3;e=(-t+GameMath.sqrt(t*t-4*e*a))/(2*e);return r.clone().multiplyScalar(e).add(i)}static computeTurnCircle(e,t,i,r){r/=degToRad(Math.abs(i));let s=rotateVec2(t.clone(),90*-Math.sign(i));return{center:isFinite(r)?s.setLength(r).add(e):e.clone(),radius:r}}}var util_geometry_THREE=__webpack_require__(70);function pointEquals(e,t){return e&&t&&e.x===t.x&&e.y===t.y||!e&&!t}function rectIntersect(e,t){return e.x<=t.x+t.width&&t.x<=e.x+e.width&&e.y<=t.y+t.height&&t.y<=e.y+e.height}function rectEquals(e,t){return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height}function circleIntersect(e,t){var i=e.center,r=t.center;return isBetween((i.x-r.x)*(i.x-r.x)+(i.y-r.y)*(i.y-r.y),(e.radius-t.radius)*(e.radius-t.radius),(e.radius+t.radius)*(e.radius+t.radius))}function circleContainsPoint(e,t){var i=e.center;return(i.x-t.x)*(i.x-t.x)+(i.y-t.y)*(i.y-t.y)<=e.radius*e.radius}function rectContainsPoint(e,t){let i=new util_geometry_THREE.Box2(new util_geometry_THREE.Vector2(e.x,e.y),new util_geometry_THREE.Vector2(e.x+e.width,e.y+e.height));return i.containsPoint(new util_geometry_THREE.Vector2(t.x,t.y))}function rectContainsRect(e,t){let i=new util_geometry_THREE.Box2(new util_geometry_THREE.Vector2(e.x,e.y),new util_geometry_THREE.Vector2(e.x+e.width,e.y+e.height));t=new util_geometry_THREE.Box2(new util_geometry_THREE.Vector2(t.x,t.y),new util_geometry_THREE.Vector2(t.x+t.width,t.y+t.height));return i.containsBox(t)}function rectClampPoint(e,t){let i=new util_geometry_THREE.Box2(new util_geometry_THREE.Vector2(e.x,e.y),new util_geometry_THREE.Vector2(e.x+e.width,e.y+e.height));return i.clampPoint(new util_geometry_THREE.Vector2(t.x,t.y),new util_geometry_THREE.Vector2)}function octileDistance(e,t){var i=Math.abs(e.x-t.x),t=Math.abs(e.y-t.y);return i+t+(Math.SQRT2-2)*Math.min(i,t)}class ObjectLiftOffEvent{constructor(e){this.gameObject=e,this.type=EventType.ObjectLiftOff}}class ObjectLandEvent{constructor(e){this.gameObject=e,this.type=EventType.ObjectLand}}const JUMPJET_ACCEL=2;class JumpjetLocomotor{static tickStationary(t,i){if(t.zone===ZoneType.Air){var r=t.tile.onBridgeLandType?i.map.tileOccupation.getBridgeOnTile(t.tile):void 0,s=!t.rules.balloonHover&&(!t.unitOrderTrait.getCurrentTask()?.preventLanding||!t.rules.hoverAttack)&&(i.map.getGroundObjectsOnTile(t.tile).find(e=>e.isBuilding()&&e.dockTrait?.isDocked(t))||i.map.getTileZone(t.tile)!==ZoneType.Water&&0<i.map.terrain.getPassableSpeed(t.tile,SpeedType.Foot,!0,!!t.tile.onBridgeLandType)&&0===i.map.terrain.findObstacles({tile:t.tile,onBridge:r},t).length);let e;e=s?(a=t.tile.z+(r?.tileElevation??0),Coords.tileHeightToWorld(a)):(n=t.tile.z+i.map.getGroundObjectsOnTile(t.tile).filter(e=>!(e.isInfantry()&&e.stance===StanceType.Paradrop)).reduce((e,t)=>Math.max(e,t.tileElevation+t.art.height),0),Coords.tileHeightToWorld(n)+t.rules.jumpjetHeight);var a,n,o=t.position.worldPosition.y;e!==o?(a=t.rules.jumpjetClimb,n=Math.abs(e-o),a=Math.sign(e-o)*Math.min(a,n),n=t.tileElevation,t.position.moveByLeptons3(new Vector3_Vector3(0,a,0)),t.moveTrait.handleElevationChange(n,i)):s&&(t.zone=ZoneType.Ground,t.onBridge=!!r,i.events.dispatch(new ObjectLandEvent(t)),(r=i.map.tileOccupation.getGroundObjectsOnTile(t.tile).find(e=>e.isOverlay()&&e.rules.crate))&&i.crateGeneratorTrait.pickupCrate(t,r,i))}}static tickCrash(e,t,i){var r=2*e.rules.jumpjetCrash;return e.direction=(e.direction-6+360)%360,new Vector3_Vector3(0,-r,0)}constructor(e){this.game=e,this.allowOutOfBounds=!0,this.currentMoveDir=new Vector2,this.currentHorizSpeed=0}onNewWaypoint(e,t,i){this.currentMoveDir=FacingUtil.toMapCoords(e.direction),this.cancelDestLeptons=void 0}tick(t,e,i,r){if(t.zone!==ZoneType.Air&&(t.onBridge=!1,t.zone=ZoneType.Air,this.game.events.dispatch(new ObjectLiftOffEvent(t))),r){if(!this.cancelDestLeptons){let e=t.tile;this.game.map.isWithinBounds(e)||(e=this.game.map.clampWithinBounds(e)),this.cancelDestLeptons=this.computeCancelDest(e,i)}i=this.cancelDestLeptons}var s=t.position.getMapPosition();let a=i.clone().sub(s),n=this.findTilesToCheckForBlockers(t.tile,s,this.currentMoveDir,a.length());var o=n.map(e=>e.z+this.game.map.getGroundObjectsOnTile(e).filter(e=>!(e.isDestroyed||e.isInfantry()&&e.stance===StanceType.Paradrop)).reduce((e,t)=>Math.max(e,t.tileElevation+t.art.height),0)).reduce((e,t)=>Math.max(e,t),0);let l=0;(void 0===this.lastClearZ||2<o-this.lastClearZ)&&(l=4);var h=Coords.tileHeightToWorld(o),c=Coords.tileHeightToWorld(o+l),d=t.position.worldPosition.y,u=FacingUtil.fromMapCoords(a),p=a.length()<t.rules.jumpjetSpeed;let g=0;h<=d&&!p&&({facing:v,delta:r}=FacingUtil.tick(t.direction,u,t.rules.jumpjetTurnRate),g=r,t.direction=v,this.currentMoveDir.copy(FacingUtil.toMapCoords(t.direction))),t.isVehicle()&&(t.spinVelocity=g);let m,y=!1,T=0,f=0;var v=t.rules.jumpjetClimb;d<c?(T=Math.min(v,c-d),m=!1,this.currentHorizSpeed=0):(this.lastClearZ=o,o=h+t.rules.jumpjetHeight,m=!0,o!==d&&(h=Math.abs(o-d),T=Math.sign(o-d)*Math.min(v,h),m=h<=v),v=this.currentHorizSpeed,this.currentHorizSpeed=Math.min(this.currentHorizSpeed+JUMPJET_ACCEL,t.rules.jumpjetSpeed),y=u===t.direction?(f=Math.min(v,a.length()),v>=a.length()):((s=v||g?TargetUtil.computeTurnCircle(s,this.currentMoveDir,Math.sign(g)*t.rules.jumpjetTurnRate,v):void 0)&&circleContainsPoint(s,i)?(f=0,this.currentHorizSpeed=0):f=v,!1));let b;b=p?(y=!0,a):this.currentMoveDir.clone().setLength(f);let w=new Vector3_Vector3(b.x,T,b.y);p=w.clone();return t.moveTrait.velocity.copy(p),{distance:w,done:y&&m}}findTilesToCheckForBlockers(e,t,i,r){r=i.clone().setLength(Math.min(r,Coords.LEPTONS_PER_TILE)).add(t).multiplyScalar(1/Coords.LEPTONS_PER_TILE).floor(),t=this.game.map.tiles.getByMapCoords(r.x,r.y);if(!t||t===e)return[e];r=Math.sign(t.rx-e.rx),t=Math.sign(t.ry-e.ry);let s=[e],a;return r&&(a=this.game.map.tiles.getByMapCoords(e.rx+r,e.ry),a&&s.push(a)),t&&(a=this.game.map.tiles.getByMapCoords(e.rx,e.ry+t),a&&s.push(a)),r&&t&&(a=this.game.map.tiles.getByMapCoords(e.rx+r,e.ry+t),a&&s.push(a)),s}computeCancelDest(e,t){var i=t.clone().multiplyScalar(1/Coords.LEPTONS_PER_TILE).floor().multiplyScalar(Coords.LEPTONS_PER_TILE),i=t.clone().sub(i);return new Vector2(e.rx,e.ry).multiplyScalar(Coords.LEPTONS_PER_TILE).add(i)}}var FlightPhase,NotifyTick_NotifyTick,DockingStatus,ManeuverType,NotifyTeleport,NotifyDestroy,DeathType,NotifyTileChange,NotifyTileChange_NotifyTileChange,NotifyElevationChange,MoveState,MoveResult,CollisionState,NotifyOwnerChange,NotifySpawn,NotifyUnspawn,NotifyAttack,VeteranLevel,NotifyCrash,ParadropState,OverlayBridgeType,NotifyAttack_NotifyAttack,CollisionType,TileDirection,SpecialWarheadType,State,NotifySuperWeaponDeactivate,NotifyDamage,TiberiumType,CubicBezierCurve3_THREE=__webpack_require__(70);class CubicBezierCurve3 extends CubicBezierCurve3_THREE.CubicBezierCurve3{constructor(e,t,i,r){super(e||new Vector3_Vector3,t||new Vector3_Vector3,i||new Vector3_Vector3,r||new Vector3_Vector3)}getPoint(e,t){return super.getPoint(e,t||new Vector3_Vector3)}}!function(e){e[e.Boost=0]="Boost",e[e.Midcourse=1]="Midcourse",e[e.Terminal=2]="Terminal"}(FlightPhase=FlightPhase||{});class MissileLocomotor{constructor(e,t){this.game=e,this.missileRules=t,this.flightPhase=FlightPhase.Boost}selectNextWaypoint(e,t){var i=t[t.length-1],t=this.game.map.tileOccupation.getBridgeOnTile(i.tile),t=i.tile.z+(t?.tileElevation??0);return this.targetPosition=Coords.tile3dToWorld(i.tile.rx+.5,i.tile.ry+.5,t),this.cruiseAltitude=Coords.tileHeightToWorld(t)+this.missileRules.altitude,i}onNewWaypoint(e,t,i){}tick(i,e,t){let r=i.position.worldPosition.clone(),s=this.targetPosition.clone().sub(r);i.zone!==ZoneType.Air&&(i.onBridge=!1,i.zone=ZoneType.Air,this.game.events.dispatch(new ObjectLiftOffEvent(i)));let a;var n;a=this.currentVelocity?(n=i.rules.speed,Math.min(this.currentVelocity.length()+this.missileRules.acceleration,n)):(p=this.missileRules.acceleration,this.missileRules.lazyCurve?this.currentVelocity=new Vector3_Vector3(s.x,0,s.z):this.currentVelocity=Coords.vecGroundToWorld(FacingUtil.toMapCoords(i.direction)),rotateVec3Towards(this.currentVelocity,new Vector3_Vector3(this.currentVelocity.x,1e8,this.currentVelocity.z),i.pitch),p),this.currentVelocity.setLength(a);let o=!1;switch(this.flightPhase){case FlightPhase.Boost:if(!(i.position.worldPosition.y>=this.cruiseAltitude)){o=!1;break}this.flightPhase=FlightPhase.Midcourse;case FlightPhase.Midcourse:var l,h=new Vector2(s.x,s.z).length();if(!this.missileRules.lazyCurve){rotateVec3Towards(this.currentVelocity,new Vector3_Vector3(this.currentVelocity.x,0,this.currentVelocity.z),i.rules.rot),this.currentVelocity.y<1&&(l=this.currentVelocity.length(),this.currentVelocity.y=0,this.currentVelocity.setLength(l)),rotateVec3Towards(this.currentVelocity,new Vector3_Vector3(s.x,this.currentVelocity.y,s.z),i.rules.rot),i.direction=FacingUtil.fromMapCoords(Coords.vecWorldToGround(this.currentVelocity)),i.pitch=Math.sign(this.currentVelocity.y)*angleDegBetweenVec3(this.currentVelocity,new Vector3_Vector3(this.currentVelocity.x,0,this.currentVelocity.z)),h/(r.y-this.targetPosition.y)<1&&(this.flightPhase=FlightPhase.Terminal);break}this.flightPhase=FlightPhase.Terminal;var c=r.clone().add(this.currentVelocity.clone().setLength(h/3/GameMath.cos(degToRad(i.pitch)))),d=this.targetPosition.clone().lerp(r,.15).setY(c.y);this.descentCurve=new CubicBezierCurve3(r,c,d,this.targetPosition);case FlightPhase.Terminal:c=this.missileRules.bodyLength;if(this.missileRules.lazyCurve){var u=this.descentCurve.getLength();this.descentTravelled??(this.descentTravelled=0),this.descentTravelled+=Math.min(a,u-c-this.descentTravelled);d=this.descentTravelled/u;let e=this.descentCurve.getPointAt(d),t=this.descentCurve.getTangentAt(d);this.currentVelocity.copy(e.sub(r));d=t.clone().setY(0);i.pitch=Math.sign(t.y-d.y)*angleDegBetweenVec3(d,t),o=1<=(this.descentTravelled+c)/u}else{rotateVec3Towards(this.currentVelocity,s,i.rules.rot),i.direction=FacingUtil.fromMapCoords(Coords.vecWorldToGround(this.currentVelocity)),i.pitch=Math.sign(this.currentVelocity.y)*angleDegBetweenVec3(this.currentVelocity,new Vector3_Vector3(this.currentVelocity.x,0,this.currentVelocity.z));u=s.length()-c;(u<a||u<1)&&(this.currentVelocity.copy(s.clone().addScalar(-c)),o=!0)}break;default:throw new Error(`Unhandled flight phase "${this.flightPhase}"`)}var p=r.clone().add(this.currentVelocity);return this.game.map.isWithinHardBounds(p)?(i.moveTrait.velocity.copy(this.currentVelocity),{distance:this.currentVelocity,done:o}):(this.game.destroyObject(i),{done:!0,distance:new Vector3_Vector3})}}class WaitMinutesTask extends WaitTicksTask{constructor(e){super(Math.floor(GameSpeed.BASE_TICKS_PER_SECOND*e*60))}}class CallbackTask extends Task{constructor(e){super(),this.cb=e}onTick(e){return this.cb(e),!0}}(NotifyTick_NotifyTick=NotifyTick_NotifyTick||{}).onTick=Symbol(),function(e){e[e.Idle=0]="Idle",e[e.MoveToQueueingTile=1]="MoveToQueueingTile",e[e.WaitForTurn=2]="WaitForTurn",e[e.MoveToDock=3]="MoveToDock",e[e.Docking=4]="Docking",e[e.Docked=5]="Docked"}(DockingStatus=DockingStatus||{});class MoveToDockTask extends Task{constructor(e,t){super(),this.game=e,this.target=t,this.useChildTargetLines=!0,this.preventOpportunityFire=!1,this.dockingStatus=DockingStatus.Idle}onStart(e){if(!this.target.dockTrait)throw new Error(`Target object "${this.target.name}" is not a valid dock`);var t;this.target.dockTrait.hasReservedDockForUnit(e)?this.dockingStatus=DockingStatus.MoveToDock:void 0!==(t=this.target.dockTrait.getFirstAvailableDockNumber())?(this.target.dockTrait.reserveDockAt(e,t),this.dockingStatus=DockingStatus.MoveToDock):this.target.helipadTrait?this.cancel():this.dockingStatus=DockingStatus.MoveToQueueingTile}onEnd(e){this.dockingStatus!==DockingStatus.Docked&&this.target.isSpawned&&(this.target.dockTrait.undockUnit(e),this.target.dockTrait.unreserveDockForUnit(e)),this.dockingStatus=DockingStatus.Idle}onTick(e){if(this.isCancelling())return!0;if(!this.isValidTarget(this.target,e))return!0;if(this.dockingStatus===DockingStatus.MoveToQueueingTile){var t=this.findReachableQueueingTile(e);if(!t)return!0;if(e.tile!==t)return this.children.push(new MoveTask(this.game,t,!1,{closeEnoughTiles:5}),new CallbackTask(()=>{e.moveTrait.lastMoveResult===MoveResult.Fail?this.cancel():e.moveTrait.lastMoveResult===MoveResult.CloseEnough&&(this.game.map.tileOccupation.isTileOccupiedBy(e.tile,this.target)||(this.dockingStatus=DockingStatus.WaitForTurn))})),!1;this.dockingStatus=DockingStatus.WaitForTurn}if(this.dockingStatus===DockingStatus.WaitForTurn){var i=this.target.dockTrait.getFirstAvailableDockNumber();if(void 0===i)return this.children.push(new WaitMinutesTask(1/60)),!1;this.target.dockTrait.reserveDockAt(e,i),this.dockingStatus=DockingStatus.MoveToDock}if(this.dockingStatus===DockingStatus.MoveToDock){var r=this.target.dockTrait.getReservedDockForUnit(e),i=this.target.dockTrait.getDockTile(r),r=Coords.vecWorldToGround(this.target.dockTrait.getDockOffset(r)).add(this.target.position.getMapPosition()).sub(new Vector2(i.rx,i.ry).multiplyScalar(Coords.LEPTONS_PER_TILE));if(e.tile!==i)return this.children.push(new MoveTask(this.game,i,!1,{targetOffset:e.isAircraft()?r:void 0,closeEnoughTiles:0,strictCloseEnough:!0}),new CallbackTask(()=>{e.moveTrait.lastMoveResult===MoveResult.Fail&&this.cancel()})),this.game.afterTick(()=>e.unitOrderTrait[NotifyTick_NotifyTick.onTick](e,this.game)),!1;this.dockingStatus=DockingStatus.Docking}if(this.dockingStatus!==DockingStatus.Docking)return!1;r=this.target.dockTrait.getReservedDockForUnit(e);return this.target.dockTrait.unreserveDockForUnit(e),this.target.dockTrait.dockUnitAt(e,r),e.isAircraft()&&e.airportBoundTrait&&this.target.helipadTrait&&(e.airportBoundTrait.preferredAirport=this.target),this.dockingStatus=DockingStatus.Docked,!0}isValidTarget(e,t){return e.isSpawned&&this.game.areFriendly(e,t)}findReachableQueueingTile(t){var e=this.target.getFoundation(),e=new Vector2(this.target.tile.rx+e.width,this.target.tile.ry+e.height),e=this.game.map.tiles.getByMapCoords(e.x,e.y);return e&&this.isValidQueueingTile(e,t)?e:new RadialTileFinder(this.game.map.tiles,this.game.map.mapBounds,this.target.tile,this.target.getFoundation(),1,1,e=>this.isValidQueueingTile(e,t)).getNextTile()}isValidQueueingTile(e,t){var i=t.rules.movementZone===MovementZone.Fly,r=t.rules.speedType,s=t.isInfantry();let a=!i&&this.game.map.terrain.getPassableSpeed(t.tile,r,s,t.onBridge)?this.game.map.terrain.getIslandIdMap(r,s):void 0;return(i||a?.get(e,!1)===a?.get(t.tile,t.onBridge)&&Math.abs(e.z-this.target.tile.z)<2&&!e.onBridgeLandType&&!this.game.map.terrain.findObstacles({tile:e,onBridge:void 0},t).length)&&!this.game.map.tileOccupation.isTileOccupiedBy(e,this.target)}}const WINGED_ACCEL=2,WINGED_DECEL=2,WINGED_CLIMB=30,STATIONARY_FACING=270,STATIONARY_THRESH=5;!function(e){e[e.None=0]="None",e[e.CircleStrafe=1]="CircleStrafe",e[e.HoverStrafe=2]="HoverStrafe"}(ManeuverType=ManeuverType||{});class WingedLocomotor{static tickStationary(s,a){if(s.zone===ZoneType.Air){var n=s.tile.onBridgeLandType?a.map.tileOccupation.getBridgeOnTile(s.tile):void 0;let e=s.rules.landable&&!s.unitOrderTrait.getCurrentTask()?.preventLanding,i=s.spawnLinkTrait?.getParent();e&&i?e=!((!i.isUnit()||!i.onBridge)&&n||i.tile!==s.tile):e&&!s.airportBoundTrait&&(e=a.map.getTileZone(s.tile)!==ZoneType.Water&&0<a.map.terrain.getPassableSpeed(s.tile,SpeedType.Foot,!0,!!s.tile.onBridgeLandType)&&0===a.map.terrain.findObstacles({tile:s.tile,onBridge:n},s).length);let r;if(e){let e=s.airportBoundTrait?.preferredAirport?.dockTrait;var o=e?.isDocked(s)||e?.hasReservedDockForUnit(s);if(!s.airportBoundTrait||o){o=o?0:STATIONARY_FACING;if(s.direction!==o)return void(s.direction=FacingUtil.tick(s.direction,o,s.rules.rot).facing)}if(s.airportBoundTrait){let e=s.airportBoundTrait.preferredAirport;if(!e?.dockTrait?.isDocked(s))return e?.dockTrait?.getAvailableDockCount()||(e=s.airportBoundTrait.findAvailableAirport(s),s.airportBoundTrait.preferredAirport=e,e&&(h=e.dockTrait.getFirstAvailableDockNumber(),e.dockTrait.reserveDockAt(s,h))),void(e?(s.unitOrderTrait.addTask(new MoveToDockTask(a,e)),s.unitOrderTrait[NotifyTick_NotifyTick.onTick](s,a)):s.crashableTrait.crash(void 0))}let t;t=i?i.tile.z+i.tileElevation:s.tile.z+(n?.tileElevation??0),r=Coords.tileHeightToWorld(t)}else{var t=s.tile.z+(n?.tileElevation??0),l=s.rules.flightLevel??a.rules.general.flightLevel;r=Coords.tileHeightToWorld(t)+l}var h=s.position.worldPosition.y;r!==h?(t=WINGED_CLIMB,l=Math.abs(r-h),t=Math.sign(r-h)*Math.min(t,l),l=s.tileElevation,s.position.moveByLeptons3(new Vector3_Vector3(0,t,0)),s.moveTrait.handleElevationChange(l,a)):e&&(s.zone=ZoneType.Ground,i?i.airSpawnTrait.storeAircraft(s,a):s.onBridge=!!n,a.events.dispatch(new ObjectLandEvent(s)),(n=a.map.tileOccupation.getGroundObjectsOnTile(s.tile).find(e=>e.isOverlay()&&e.rules.crate))&&a.crateGeneratorTrait.pickupCrate(s,n,a))}}static tickCrash(e,t,i){var r=WINGED_CLIMB;i.rollDelta??(i.rollDelta=t.generateRandomInt(-15,15)),i.pitchDelta??(i.pitchDelta=t.generateRandomInt(0,15)),e.roll+=i.rollDelta,e.pitch+=i.pitchDelta;e=Coords.vecWorldToGround(e.moveTrait.velocity);return new Vector3_Vector3(e.x,-r,e.y)}constructor(e){this.game=e,this.allowOutOfBounds=!0,this.lastDestLeptons=new Vector2,this.currentMoveDir=new Vector2,this.currentHorizSpeed=0,this.maneuverType=ManeuverType.None,this.deceleratingToTurn=!1}onNewWaypoint(e,t,i){this.currentHorizSpeed=Coords.vecWorldToGround(e.moveTrait.velocity).length(),this.cancelDestLeptons=void 0}tick(t,e,i,r){if(r){if(!this.cancelDestLeptons){let e=t.tile;this.game.map.isWithinBounds(e)||(e=this.game.map.clampWithinBounds(e)),this.cancelDestLeptons=this.computeCancelDest(e,i)}i=this.cancelDestLeptons}var s=t.position.getMapPosition();let a=i.clone().sub(s);var n=a.length();this.lastDestLeptons.equals(i)||(this.lastDestLeptons.copy(i),r?this.maneuverType=ManeuverType.HoverStrafe:t.zone===ZoneType.Air&&this.currentHorizSpeed<STATIONARY_THRESH?this.maneuverType=n>Coords.LEPTONS_PER_TILE?ManeuverType.CircleStrafe:ManeuverType.HoverStrafe:this.maneuverType=ManeuverType.None,this.deceleratingToTurn=!1),t.zone!==ZoneType.Air&&(t.onBridge=!1,t.zone=ZoneType.Air,this.game.events.dispatch(new ObjectLiftOffEvent(t)));var o=t.tile.onBridgeLandType?this.game.map.tileOccupation.getBridgeOnTile(t.tile):void 0,l=t.tile.z+(o?.tileElevation??0),h=t.rules.flightLevel??this.game.rules.general.flightLevel,c=Coords.tileHeightToWorld(l)+h,r=t.position.worldPosition.y,d=FacingUtil.fromMapCoords(a);t.direction===d&&this.maneuverType===ManeuverType.None&&n<=Coords.LEPTONS_PER_TILE?this.maneuverType=ManeuverType.HoverStrafe:t.direction===d&&this.maneuverType===ManeuverType.CircleStrafe&&(this.maneuverType=ManeuverType.None);let u;switch(this.maneuverType){case ManeuverType.HoverStrafe:if(t.attackTrait?.currentTarget){let e=Coords.vecWorldToGround(t.attackTrait.currentTarget.getWorldCoords());u=FacingUtil.fromMapCoords(e.sub(s))}else u=t.airportBoundTrait?.preferredAirport?.dockTrait?.hasReservedDockForUnit(t)?0:STATIONARY_FACING;break;case ManeuverType.CircleStrafe:case ManeuverType.None:u=d;break;default:throw new Error('Unknown maneuver type "'+this.maneuverType)}var{facing:p,delta:g}=FacingUtil.tick(t.direction,u,t.rules.rot);t.direction=p,t.roll=Math.sign(g)*t.rules.pitchAngle;let m;switch(this.maneuverType){case ManeuverType.HoverStrafe:m=d;break;case ManeuverType.CircleStrafe:m=(p-90*Math.sign(g)+360)%360;break;case ManeuverType.None:m=p;break;default:throw new Error('Unknown maneuver type "'+this.maneuverType)}void 0===this.thrustFacing&&(this.thrustFacing=m);var o=this.currentHorizSpeed>STATIONARY_THRESH?t.rules.rot:Number.POSITIVE_INFINITY,{facing:l,delta:h}=FacingUtil.tick(this.thrustFacing,m,o);this.thrustFacing=l,this.currentMoveDir.copy(FacingUtil.toMapCoords(this.thrustFacing));let y=!1,T=0,f=0;o=WINGED_CLIMB;let v=!0;c!==r&&(l=Math.abs(c-r),T=Math.sign(c-r)*Math.min(o,l),v=l<=o);let b=t.rules.speed;n<=Coords.LEPTONS_PER_TILE&&this.maneuverType!==ManeuverType.CircleStrafe&&(b=lerp(1,b/2,GameMath.sqrt(n/Coords.LEPTONS_PER_TILE))),this.deceleratingToTurn?this.currentHorizSpeed=Math.max(0,this.currentHorizSpeed-WINGED_DECEL):this.currentHorizSpeed=Math.min(this.currentHorizSpeed+WINGED_ACCEL,b);o=this.currentHorizSpeed;this.deceleratingToTurn=!1,y=h?(h=o||h?TargetUtil.computeTurnCircle(s,this.currentMoveDir,Math.sign(h)*t.rules.rot,o):void 0,0!==o&&!circleContainsPoint(h,i)||(this.maneuverType===ManeuverType.HoverStrafe||n>Coords.LEPTONS_PER_TILE?this.deceleratingToTurn=!0:this.maneuverType===ManeuverType.None&&(this.maneuverType=ManeuverType.HoverStrafe)),f=o,!1):(f=Math.min(o,n),n<=o);let w;w=n<1?(y=!0,a):y?a:this.currentMoveDir.clone().setLength(f);let S=new Vector3_Vector3(w.x,T,w.y);n=S.clone();return t.moveTrait.velocity.copy(n),{distance:S,done:y&&v}}computeCancelDest(e,t){var i=t.clone().multiplyScalar(1/Coords.LEPTONS_PER_TILE).floor().multiplyScalar(Coords.LEPTONS_PER_TILE),i=t.clone().sub(i);return new Vector2(e.rx,e.ry).multiplyScalar(Coords.LEPTONS_PER_TILE).add(i)}}class LocomotorFactory{constructor(e){this.game=e}create(e){var t=e.rules.locomotor;switch(t){case LocomotorType.Infantry:return new FootLocomotor(this.game);case LocomotorType.Jumpjet:return new JumpjetLocomotor(this.game);case LocomotorType.Vehicle:case LocomotorType.Ship:return new DriveLocomotor(this.game);case LocomotorType.Chrono:return e.isVehicle()&&e.harvesterTrait&&e.rules.teleporter?new DriveLocomotor(this.game):new ChronoLocomotor(this.game);case LocomotorType.Aircraft:return new WingedLocomotor(this.game);case LocomotorType.Missile:return new MissileLocomotor(this.game,this.game.rules.general.getMissileRules(e.name));case LocomotorType.Hover:return new HoverLocomotor(this.game.rules.general.hover);default:throw new Error("Unhandled locomotor type "+t)}}}class RandomTileFinder{constructor(e,t,i,r,s,a,n=!1,o=!0){this.tiles=e,this.mapBounds=t,this.startTile=i,this.maxDistance=r,this.rng=s,this.predicate=a,this.includeStartTile=n,this.checkBounds=o,this.pool=[],this.pool=new Array(GameMath.pow(2*this.maxDistance+1,2)).fill(0).map((e,t)=>t),this.generator=this.generate()}getNextTile(){return this.generator.next().value}*generate(){for(var e=(e,t)=>{t=this.tiles.getByMapCoords(e,t);if(this.includeStartTile||t!==this.startTile)return t&&(!this.checkBounds||this.mapBounds.isWithinBounds(t))&&this.predicate(t)?t:void 0},t=2*this.maxDistance+1;this.pool.length;){var i=1<this.pool.length?this.rng.generateRandomInt(0,this.pool.length):0,r=this.pool.splice(i,1)[0],i=r%t,r=Math.floor(r/t),r=e(this.startTile.rx-this.maxDistance+i,this.startTile.ry-this.maxDistance+r);r&&(yield r)}}}class ObjectTeleportEvent{constructor(e,t,i){this.target=e,this.isChronoshift=t,this.prevTile=i,this.type=EventType.ObjectTeleport}}(NotifyTeleport=NotifyTeleport||{}).onBeforeTeleport=Symbol();class ScatterPositionHelper{constructor(e){this.game=e,this.movePositionHelper=new MovePositionHelper(e.map)}findPositions(e,t){let i=new Set,r=new Map;for(var s of e){var a=this.findFreeMovePosition(s,i,t);a&&(r.set(s,a),i.add(a.tile))}return r}findFreeMovePosition(i,e,{ignoredBlockers:t,excludedTiles:r,noSlopes:s}={}){let a=this.game.map,n=i.onBridge?a.tileOccupation.getBridgeOnTile(i.tile):void 0,o=new RandomTileFinder(a.tiles,a.mapBounds,i.tile,1,this.game,e=>{if(r?.includes(e))return!1;var t=a.tileOccupation.getBridgeOnTile(e);return(t&&this.movePositionHelper.isEligibleTile(e,t,n,i.tile)||this.movePositionHelper.isEligibleTile(e,void 0,n,i.tile))&&(!s||0===e.rampType)}),l,h;for(;;){var c=o.getNextTile();if(!c)break;if(l=c,h=a.tileOccupation.getBridgeOnTile(c),h&&!this.movePositionHelper.isEligibleTile(c,h,n,i.tile)&&(h=void 0),!e.has(c)){let e=a.terrain.findObstacles({tile:c,onBridge:h},i);if(t&&t.length&&(e=e.filter(e=>!t.includes(e.obj))),!e.length)break}}if(l)return{tile:l,onBridge:h}}}class ScatterTask extends Task{constructor(e,t,i){super(),this.game=e,this.target=t,this.options=i}onStart(i){if(!i.moveTrait.isDisabled()&&i.rules.movementZone!==MovementZone.Fly){let e,t;if(this.target)({tile:e,toBridge:t}=this.target);else{i=new ScatterPositionHelper(this.game).findPositions([i],this.options).get(i);if(!i)return;e=i.tile,t=!!i.onBridge}this.children.push(new MoveTask(this.game,e,t,{closeEnoughTiles:0,ignoredBlockers:this.options?.ignoredBlockers}))}}onTick(e){return!0}}const SPEED_MULT=1.5,PLANNING_BAILOUT_TICKS=200,MoveTask_RETRY_TICKS=40,MAX_UNREACH_TILES_BAIL=5;class MoveTask extends Task{constructor(e,t,i,r){super(),this.game=e,this.targetTile=t,this.toBridge=i,this.options=r,this.preventOpportunityFire=!1,this.logger=AppLogger.get("move"),this.destinationLeptons=new Vector2,this.currentWaypointLeptons=new Vector2,this.needsPathUpdate=!1,this.allObstaclesAreBlockers=!1,this.blockedPathNodes=[],this.unreachableTargets=[],this.pushTried=!1,this.cancelProcessed=!1,this.cancelRepositionPending=!1,this.targetLinesConfig={pathNodes:[]}}duplicate(){return new MoveTask(this.game,this.targetTile,this.toBridge,this.options)}setForceMove(e){e?(this.options??(this.options={}),this.options.forceMove=!0):this.options?.forceMove&&(this.options.forceMove=void 0)}onStart(e){if(e.moveTrait.currentWaypoint)throw new Error("Nested move tasks are not supported");void 0===e.moveTrait.locomotor&&(e.moveTrait.locomotor=new LocomotorFactory(this.game).create(e)),e.moveTrait.lastTargetOffset?this.targetOffset=e.moveTrait.lastTargetOffset:this.targetOffset=this.computeTargetOffset(e),e.moveTrait.lastVelocity&&(e.moveTrait.velocity=e.moveTrait.lastVelocity),this.path||(this.groundPathPlan?(this.groundPathPlan.path[this.groundPathPlan.path.length-1].tile===e.tile?this.path=this.applyGroundPathPlan(this.groundPathPlan):this.computePath(e,e.moveTrait.locomotor),this.groundPathPlan=void 0):this.computePath(e,e.moveTrait.locomotor),this.targetLinesConfig.isRecalc=!1),this.updateDestination(this.path,this.targetOffset),e.moveTrait.moveState=MoveState.ReachedNextWaypoint,e.moveTrait.lastMoveResult=void 0,e.moveTrait.lastTargetOffset=void 0,e.moveTrait.lastVelocity=void 0}computeTargetOffset(e){return this.options?.targetOffset??(e.isInfantry()?e.position.getTileOffset():e.position.computeSubCellOffset(0))}computePath(e,t,i=!1){let r;if(this.options?.allowOutOfBoundsTarget||this.game.map.mapBounds.isWithinBounds(this.targetTile))if(e.rules.movementZone===MovementZone.Fly)r=this.computeAirPath(e);else if(t.ignoresTerrain)r=this.computeDirectJumpPath(e);else{t=this.computeGroundPath(e);if(i&&!t.path.length)return!1;r=this.applyGroundPathPlan(t)}else r=[];return e.rules.movementZone===MovementZone.Fly?(this.targetLinesConfig.pathNodes=r.map(({tile:e,onBridge:t})=>({tile:e,onBridge:t})),r.length&&(this.targetLinesConfig.pathNodes[0].onBridge=this.toBridge?this.game.map.tileOccupation.getBridgeOnTile(this.targetTile):void 0)):this.targetLinesConfig.pathNodes=r,this.path=r,!0}computeAirPath(e){return[{tile:this.targetTile,onBridge:void 0},{tile:e.tile,onBridge:void 0}]}computeDirectJumpPath(t){let i=this.game.map;var e=t.onBridge?i.tileOccupation.getBridgeOnTile(t.tile):void 0;let r=this.targetTile,s=this.toBridge?i.tileOccupation.getBridgeOnTile(this.targetTile):void 0,a=this.options?.ignoredBlockers;var n=new RadialTileFinder(i.tiles,i.mapBounds,r,{width:1,height:1},0,5,e=>0<i.terrain.getPassableSpeed(e,t.rules.speedType,t.isInfantry(),!!e.onBridgeLandType,a)&&!i.terrain.findObstacles({tile:e,onBridge:!!e.onBridgeLandType},t).find(e=>!a?.includes(e.obj))).getNextTile();return n?(n!==r&&(r=n,s=i.tileOccupation.getBridgeOnTile(r)),[{tile:r,onBridge:s},{tile:t.tile,onBridge:e}]):[]}computeGroundPath(t){let e=t.tile,i=t.onBridge?this.game.map.tileOccupation.getBridgeOnTile(e):void 0;t.moveTrait.moveState===MoveState.Moving&&t.moveTrait.currentWaypoint&&(e=t.moveTrait.currentWaypoint.tile,i=t.moveTrait.currentWaypoint.onBridge);let r={path:[],ignoredBlockers:[],blockedPathNodes:[]};const s=this.game.map.getObjectsOnTile(e).find(e=>e.isBuilding());if(s&&!this.game.map.terrain.getPassableSpeed(e,t.rules.speedType,t.isInfantry(),!1)){var a=this.options?.ignoredBlockers?.includes(s);if(a||r.ignoredBlockers.push(s),!a&&s.dockTrait){let t=new Set(s.dockTrait?.getAllDockTiles()),e=this.game.map.tileOccupation.calculateTilesForGameObject(s.tile,s);e.filter(e=>!t.has(e)).forEach(e=>r.blockedPathNodes.push({node:{tile:e,onBridge:void 0},obj:s}))}}var n=this.game.map.getGroundObjectsOnTile(this.targetTile).find(e=>(e.isInfantry()||e.isVehicle())&&e.disguiseTrait?.hasTerrainDisguise()&&!(this.game.alliances.haveSharedIntel(t.owner,e.owner)||e.owner.sharedDetectDisguiseTrait?.has(t)));n&&(a=this.toBridge?this.game.map.tileOccupation.getBridgeOnTile(this.targetTile):void 0,r.blockedPathNodes.push({node:{tile:this.targetTile,onBridge:a},obj:n}));let o=[...new Set([...this.options?.ignoredBlockers??[],...r.ignoredBlockers])],l=[...this.blockedPathNodes,...r.blockedPathNodes];n=this.game.map.terrain.computePath(t.rules.speedType,t.isInfantry(),e,!!i,this.targetTile,this.toBridge,{maxExpandedNodes:this.allObstaclesAreBlockers?Math.min(300,this.options?.maxExpandedPathNodes??Number.POSITIVE_INFINITY):this.options?.maxExpandedPathNodes,bestEffort:!this.options?.strictCloseEnough,ignoredBlockers:[...new Set([...o,...this.options?.pathFinderIgnoredBlockers??[]])],excludeTiles:this.allObstaclesAreBlockers||l.length?e=>this.nodeIsBlockedForPathfinding(e,t,o,l):void 0});return r.path=n,r}nodeIsBlockedForPathfinding(t,e,i,r){return this.allObstaclesAreBlockers?!!this.game.map.terrain.findObstacles(t,e).find(e=>!i?.includes(e.obj)):!!r.find(({node:e})=>e.tile===t.tile&&e.onBridge===t.onBridge)}applyGroundPathPlan(e){var t;return this.blockedPathNodes=this.blockedPathNodes.filter(e=>e.obj.isSpawned&&e.node.tile===e.obj.tile),e.ignoredBlockers.length&&(this.options??(this.options={}),(t=this.options).ignoredBlockers??(t.ignoredBlockers=[]),this.options.ignoredBlockers.push(...e.ignoredBlockers)),this.blockedPathNodes.push(...e.blockedPathNodes),e.path}updateDestination(e,t){e=e.length?e[0].tile:this.targetTile;this.destinationLeptons.set(e.rx*Coords.LEPTONS_PER_TILE,e.ry*Coords.LEPTONS_PER_TILE).add(t)}canStopAtTile(t,i,r){if(t.zone===ZoneType.Air){if((!t.isAircraft()||!t.airportBoundTrait)&&!t.rules.spawned&&(!this.options?.forceMove||!t.rules.balloonHover||t.rules.hoverAttack)&&(!this.game.map.terrain.getPassableSpeed(i,SpeedType.Amphibious,!1,r)||this.game.map.getObjectsOnTile(i).filter(e=>e.isBuilding()&&!e.isDestroyed&&!e.dockTrait?.hasReservedDockForUnit(t)&&!t.rules.dock.includes(e.name)||e.isUnit()&&e.tile===i&&e.moveTrait.moveState!==MoveState.Moving&&e!==t).length))return!1}else if(t.isInfantry()){let e=this.game.map.getGroundObjectsOnTile(i).filter(e=>e.isInfantry()&&e.tile===i&&e.onBridge===r&&e.moveTrait.moveState!==MoveState.Moving&&e!==t);if(2<e.length||e.find(e=>e.position.subCell===t.position.subCell))return!1}return!(t.zone!==ZoneType.Air&&t.rules.tooBigToFitUnderBridge&&!r&&i.onBridgeLandType&&this.game.map.tileOccupation.getBridgeOnTile(i)?.isHighBridge())&&!(!this.isCancelling()&&this.options?.strictCloseEnough&&void 0!==this.options?.closeEnoughTiles&&!this.isCloseEnoughToDest(t,i,this.options.closeEnoughTiles))}isCloseEnoughToDest(e,t,i){if(void 0===i)return!0;let r=new RangeHelper(this.game.map.tileOccupation);return!(r.tileDistance(this.targetTile,t)>i)}hasReachedDestination(e){return!this.path.length}updateTarget(e,t,i=!1){this.needsPathUpdate=!0,this.targetChangeRequested={tile:e,toBridge:t,onlyIfPathExists:i}}onEnd(e){e.moveTrait.collisionState=CollisionState.Resolved,e.moveTrait.currentWaypoint=void 0,this.targetOffset.equals(this.computeTargetOffset(e))||(e.moveTrait.lastTargetOffset=this.targetOffset)}forceCancel(e){return!(!this.cancellable||this.children.some(e=>!e.cancellable))&&(!(!this.options?.allowOutOfBoundsTarget&&!this.game.map.isWithinBounds(e.tile))&&(this.status!==TaskStatus.Running&&this.status!==TaskStatus.Cancelling||(e.moveTrait.unreservePathNodes(),e.moveTrait.lastMoveResult=MoveResult.Cancel,this.onEnd(e),e.moveTrait.lastTargetOffset=this.targetOffset,e.moveTrait.lastVelocity=e.moveTrait.velocity.clone()),this.status=TaskStatus.Cancelled,!0))}onTick(s){if(s.moveTrait.isDisabled()&&s.moveTrait.moveState===MoveState.ReachedNextWaypoint)return!!this.isCancelling()&&(s.moveTrait.lastMoveResult=MoveResult.Cancel,!0);var e;this.needsPathUpdate&&(s.moveTrait.moveState===MoveState.PlanMove&&(this.inPlanningForTicks=void 0,s.moveTrait.currentWaypoint=void 0,s.moveTrait.collisionState=CollisionState.Resolved,s.moveTrait.moveState=MoveState.ReachedNextWaypoint,s.moveTrait.velocity.set(0,0,0)),e=this.targetTile,r=this.toBridge,this.targetChangeRequested&&(this.targetTile=this.targetChangeRequested.tile,this.toBridge=this.targetChangeRequested.toBridge),this.computePath(s,s.moveTrait.locomotor,this.targetChangeRequested?.onlyIfPathExists)?(this.path.length||this.unreachableTargets.push({tile:this.targetTile,toBridge:this.toBridge}),this.updateDestination(this.path,this.targetOffset),this.allObstaclesAreBlockers=!1):(this.targetTile=e,this.toBridge=r,this.targetLinesConfig.pathNodes=[...this.targetLinesConfig.pathNodes]),this.targetLinesConfig.isRecalc=!this.targetChangeRequested,this.targetChangeRequested=void 0,this.needsPathUpdate=!1);let i=this.game.map;if(s.moveTrait.moveState===MoveState.ReachedNextWaypoint){s.moveTrait.unreservePathNodes();var r=this.path.findIndex(e=>e===s.moveTrait.currentWaypoint);if(-1!==r?this.path.splice(r):this.path.pop(),s.moveTrait.currentWaypoint=void 0,this.isCancelling()?!this.cancelProcessed:this.hasReachedDestination(s)){var a=!this.isCancelling()&&!this.isCloseEnoughToDest(s,s.tile,this.options?.closeEnoughTiles);if(!a&&this.canStopAtTile(s,s.tile,s.onBridge))return s.moveTrait.lastMoveResult=this.isCancelling()?MoveResult.Cancel:MoveResult.Success,!0;{if(this.unreachableTargets.length>MAX_UNREACH_TILES_BAIL)return s.moveTrait.lastMoveResult=MoveResult.Fail,this.log(s,"bail_max_unreachable_dest"),!0;let e=s.tile,t=s.onBridge?i.tileOccupation.getBridgeOnTile(e):void 0;a&&(e=this.targetTile,t=this.toBridge?i.tileOccupation.getBridgeOnTile(e):void 0);r=this.findRelocationTile(e,t,s);if(!r)return s.moveTrait.lastMoveResult=a?MoveResult.Fail:MoveResult.CloseEnough,this.log(s,"bail_no_free_dest"),!0;a=!t||t.isHighBridge()?i.tileOccupation.getBridgeOnTile(r):void 0;return this.updateTarget(r,!!a),this.isCancelling()&&(this.cancelProcessed=!0,this.cancelRepositionPending=!0),!1}}if(this.cancelProcessed&&!this.path.length)return s.moveTrait.lastMoveResult=MoveResult.Cancel,!0;this.cancelProcessed=!1,s.moveTrait.moveState=MoveState.PlanMove;let e=s.moveTrait.locomotor;s.moveTrait.currentWaypoint=e.selectNextWaypoint?e.selectNextWaypoint(s,this.path):this.path[this.path.length-1],this.currentWaypointLeptons.set(s.moveTrait.currentWaypoint.tile.rx,s.moveTrait.currentWaypoint.tile.ry).multiplyScalar(Coords.LEPTONS_PER_TILE).add(this.targetOffset);a=e.onNewWaypoint(s,this.currentWaypointLeptons,this.destinationLeptons);if(a)return this.children.push(...a),!1}if(s.moveTrait.moveState===MoveState.PlanMove){if(this.isCancelling()&&!this.cancelRepositionPending)return s.moveTrait.currentWaypoint=void 0,s.moveTrait.moveState=MoveState.ReachedNextWaypoint,this.onTick(s);if(this.inPlanningForTicks=void 0===this.inPlanningForTicks?0:this.inPlanningForTicks+1,this.inPlanningForTicks>PLANNING_BAILOUT_TICKS)return this.needsPathUpdate=!0,this.allObstaclesAreBlockers=!0,s.moveTrait.velocity.set(0,0,0),this.log(s,"repath_plan_timeout"),!1;if(s.rules.movementZone!==MovementZone.Fly&&!s.moveTrait.locomotor.ignoresTerrain){let t=this.path.slice(this.path.indexOf(s.moveTrait.currentWaypoint)).reverse();var n,o,l,h=s.moveTrait.velocity.length();for(n of t)n.onBridge?.isDestroyed&&(n.onBridge=void 0);for(o of t){if(!i.terrain.getPassableSpeed(o.tile,s.rules.speedType,s.isInfantry(),!!o.onBridge,this.options?.ignoredBlockers))return this.options?.stopOnBlocker&&i.terrain.findObstacles(o,s).some(e=>e.obj===this.options.stopOnBlocker)?(s.moveTrait.lastMoveResult=MoveResult.CloseEnough,!0):(this.needsPathUpdate=!0,s.moveTrait.currentWaypoint=void 0,s.moveTrait.moveState=MoveState.ReachedNextWaypoint,this.onTick(s));if(!o.onBridge){var c=i.getGroundObjectsOnTile(o.tile).find(e=>e.isOverlay()&&e.rules.crate);if(c)if(this.game.crateGeneratorTrait.peekInsideCrate(c)===PowerupType.Unit){this.game.crateGeneratorTrait.pickupCrate(s,c,this.game);c=this.game.map.getGroundObjectsOnTile(o.tile).find(e=>e.isUnit()&&!e.onBridge);if(c)return this.needsPathUpdate=!0,this.blockedPathNodes.push({node:o,obj:c}),s.moveTrait.currentWaypoint=void 0,s.moveTrait.moveState=MoveState.ReachedNextWaypoint,this.onTick(s)}}for(l of i.terrain.findObstacles(o,s).filter(e=>!this.options?.ignoredBlockers?.includes(e.obj))){if(l.static)return this.needsPathUpdate=!0,s.moveTrait.currentWaypoint=void 0,s.moveTrait.moveState=MoveState.ReachedNextWaypoint,this.onTick(s);if(l.obj.rules.crushable){if([SpeedType.Track,SpeedType.Hover].includes(s.rules.speedType)&&s.crusher&&(!l.obj.isTechno()||!this.game.areFriendly(l.obj,s)))continue;if(!l.obj.isTechno())return this.needsPathUpdate=!0,s.moveTrait.currentWaypoint=void 0,s.moveTrait.moveState=MoveState.ReachedNextWaypoint,this.onTick(s)}if(l.obj.isTerrain()){if(!s.isInfantry())throw new Error(`Obstacle ${l.obj.name} should be a blocker for non infantry`);var d=this.findFreeSubCell(s,o);return void 0!==d?this.relocateToSubCell(s,d):(this.needsPathUpdate=!0,this.blockedPathNodes.push({node:o,obj:l.obj}),s.moveTrait.currentWaypoint=void 0,s.moveTrait.moveState=MoveState.ReachedNextWaypoint),this.onTick(s)}if(!l.obj.isTechno())throw new Error("Unexpected obstacle of type "+l.obj.type);const f=l.obj;var u=f.isUnit()?f.moveTrait.velocity.length():0;if(!f.isAircraft()||f.zone!==ZoneType.Ground||!this.options?.ignoredBlockers?.some(e=>e.isBuilding()&&e.dockTrait?.isDocked(f))){if(1===t.length&&f.isUnit()&&u&&h&&h<=u&&s.direction===f.direction&&f.tile===o.tile&&f.moveTrait.currentWaypoint?.tile!==o.tile)break;if(f.isBuilding()||f.moveTrait.moveState===MoveState.Idle||f.moveTrait.collisionState!==CollisionState.Resolved){if(!h&&s.moveTrait.collisionState!==CollisionState.Resolved&&f.isUnit()&&f.moveTrait.collisionState!==CollisionState.Resolved)return this.inPlanningForTicks+1>PLANNING_BAILOUT_TICKS&&(this.needsPathUpdate=!0,this.allObstaclesAreBlockers=!0,this.log(s,"repath_waited_too_long_blocker "+f.id),s.moveTrait.velocity.set(0,0,0)),!1;{if(f.isInfantry()&&s.isInfantry()&&f.moveTrait.collisionState===CollisionState.Resolved){var p=this.findFreeSubCell(s,o);if(void 0!==p)return this.relocateToSubCell(s,p),this.onTick(s)}d=findIndexReverse(this.path.slice(0,this.path.indexOf(o)),e=>!i.terrain.findObstacles(e,s).filter(e=>!this.options?.ignoredBlockers?.includes(e.obj)).length);if(-1===d){if(this.canStopAtTile(s,s.tile,s.onBridge)&&this.isCloseEnoughToDest(s,s.tile,this.options?.closeEnoughTiles))return s.moveTrait.lastMoveResult=MoveResult.CloseEnough,this.log(s,"bail_waypoints_blocked_close_enough"),!0;if(!(0===this.options?.closeEnoughTiles||Math.abs(s.tile.rx-this.targetTile.rx)<=1&&Math.abs(s.tile.ry-this.targetTile.ry)<=1))return this.needsPathUpdate=!0,this.blockedPathNodes.push(...this.path.slice(0,this.path.indexOf(o)+1).map(e=>({node:e,obj:i.terrain.findObstacles(e,s)[0].obj}))),s.moveTrait.velocity.set(0,0,0),this.log(s,"repath_waypoints_blocked_too_far"),!1}let e;if(e=-1!==d?(p=this.path[d],i.terrain.computePath(s.rules.speedType,s.isInfantry(),s.tile,s.onBridge,p.tile,!!p.onBridge,{maxExpandedNodes:15,bestEffort:!1,excludeTiles:e=>!!i.terrain.findObstacles(e,s).filter(e=>!this.options?.ignoredBlockers?.includes(e.obj)).length,ignoredBlockers:this.options?.ignoredBlockers})):[],e.length||f.owner!==s.owner||1!==t.length)return e.length?(this.path.splice(d,this.path.length,...e),s.moveTrait.currentWaypoint=void 0,s.moveTrait.moveState=MoveState.ReachedNextWaypoint,this.onTick(s)):((g=this.selectWeaponVsObstacle(s,f))?(this.children.push(s.attackTrait.createAttackTask(this.game,f,f.tile,g,{passive:!0,holdGround:!0})),s.moveTrait.velocity.set(0,0,0)):this.options?.forceWaitOnPathBlocked?(this.children.push(new WaitTicksTask(MoveTask_RETRY_TICKS)),this.inPlanningForTicks=0,s.moveTrait.velocity.set(0,0,0),s.moveTrait.collisionState=CollisionState.Waiting):(this.needsPathUpdate=!0,this.blockedPathNodes.push({node:o,obj:f}),f.isBuilding()&&(this.allObstaclesAreBlockers=!0),this.log(s,"repath_unavoidable_blocker "+f.id),s.moveTrait.velocity.set(0,0,0)),!1);g=f.unitOrderTrait.hasTasks();if(this.pushTried||f.isBuilding()||f.moveTrait.collisionState===CollisionState.Waiting||g||f.isAircraft()&&f.missileSpawnTrait)return!this.options?.forceWaitOnPathBlocked&&(f.isBuilding()||g&&f.moveTrait.moveState===MoveState.Idle||this.inPlanningForTicks+MoveTask_RETRY_TICKS>PLANNING_BAILOUT_TICKS)?(this.needsPathUpdate=!0,this.allObstaclesAreBlockers=!0,this.log(s,"repath_blocker_busy_wait_timeout "+f.id),s.moveTrait.velocity.set(0,0,0)):(this.children.push(new WaitTicksTask(MoveTask_RETRY_TICKS)),this.options?.forceWaitOnPathBlocked?this.inPlanningForTicks=0:this.inPlanningForTicks+=MoveTask_RETRY_TICKS,s.moveTrait.velocity.set(0,0,0),s.moveTrait.collisionState=CollisionState.Waiting),!1;g=new Vector2(f.tile.rx-s.tile.rx,f.tile.ry-s.tile.ry);return this.pushTried=!0,f.unitOrderTrait.addTask(new MoveAsideTask(this.game,g)),this.children.push(new WaitTicksTask(1)),s.moveTrait.velocity.set(0,0,0),s.moveTrait.collisionState=CollisionState.Waiting,this.log(s,"push "+f.id),!1}}if(f.isInfantry()&&s.isInfantry()){var g=this.findFreeSubCell(s,o);if(void 0!==g)return this.relocateToSubCell(s,g),this.onTick(s)}if(!h)return this.inPlanningForTicks>MoveTask_RETRY_TICKS&&(s.moveTrait.collisionState=CollisionState.Waiting),!1;if(180===Math.abs(s.direction-f.direction))return s.moveTrait.velocity.set(0,0,0),s.moveTrait.collisionState=CollisionState.Waiting,!1;if(Math.abs(s.direction-f.direction)<=45&&h>u*SPEED_MULT){u=this.path.indexOf(o);if(5<=u){let e=findIndexReverse(this.path.slice(0,u-5),e=>!i.terrain.findObstacles(e,s).length);if(-1!==e){u=this.path[e],u=i.terrain.computePath(s.rules.speedType,s.isInfantry(),s.tile,s.onBridge,u.tile,!!u.onBridge,{maxExpandedNodes:15,bestEffort:!1,excludeTiles:t=>!!i.terrain.findObstacles(t,s).length||this.path.findIndex(e=>e.tile===t.tile&&e.onBridge===t.onBridge)>e});if(u.length)return this.path.splice(e,this.path.length,...u),s.moveTrait.currentWaypoint=void 0,s.moveTrait.moveState=MoveState.ReachedNextWaypoint,this.onTick(s)}}return s.moveTrait.collisionState=CollisionState.Waiting,s.moveTrait.velocity.set(0,0,0),!1}return s.moveTrait.velocity.set(0,0,0),s.moveTrait.collisionState=CollisionState.Waiting,!1}}}if(s.rules.speedType===SpeedType.Track&&h){var m,y=this.path.indexOf(s.moveTrait.currentWaypoint);if(0<y){let t=this.path[y-1];for(m of i.getGroundObjectsOnTile(t.tile).filter(e=>e.isUnit()&&e.onBridge===!!t.onBridge&&e.rules.crushable&&e.veteranTrait?.hasVeteranAbility(VeteranAbility.SCATTER)&&!this.game.areFriendly(e,s)))m.unitOrderTrait.hasTasks()||m.unitOrderTrait.addTask(new ScatterTask(this.game))}}s.moveTrait.reservedPathNodes.length||(s.moveTrait.reservedPathNodes.push(...t),t.forEach(e=>{i.tileOccupation.occupySingleTile(e.tile,s)}))}s.moveTrait.moveState=MoveState.Moving,this.inPlanningForTicks=void 0,this.unreachableTargets.length=0,this.pushTried=!1,s.moveTrait.collisionState===CollisionState.Waiting&&(s.moveTrait.collisionState=CollisionState.Resolved)}if(s.moveTrait.moveState===MoveState.Moving){let e=s.moveTrait.locomotor,{distance:t,done:i,isTeleport:r}=e.tick(s,this.currentWaypointLeptons,this.destinationLeptons,(this.isCancelling()||!this.path.length)&&!this.cancelRepositionPending);if(r&&s.traits.filter(NotifyTeleport).forEach(e=>{e[NotifyTeleport.onBeforeTeleport](s,this.game,!0,!0)}),t.length()){a=s.tile,y=e.allowOutOfBounds;if(t.y?(T=s.tileElevation,s.position.moveByLeptons3(t,y),s.moveTrait.handleElevationChange(T,this.game)):s.position.moveByLeptons(t.x,t.z,y),s.tile!==a){var T=s.onBridge?this.game.map.tileOccupation.getBridgeOnTile(a):void 0,y=findReverse(this.path,e=>e.tile===s.tile);let e=y?y.onBridge:T||s.moveTrait.currentWaypoint.onBridge?this.game.map.tileOccupation.getBridgeOnTile(s.tile):void 0;if(e?.isDestroyed&&(e=void 0),s.moveTrait.handleTileChange(a,e,!1,this.game,r),r&&(s.moveTrait.lastTeleportTick=this.game.currentTick,this.game.events.dispatch(new ObjectTeleportEvent(s,!0,a))),s.isDestroyed)return!0}}if(i)return s.moveTrait.moveState=MoveState.ReachedNextWaypoint,this.onTick(s)}return!1}selectWeaponVsObstacle(e,t){let i;if(!this.game.areFriendly(t,e)&&e.attackTrait&&!e.attackTrait.isDisabled()&&e.attackTrait.isIdle()&&(i=e.attackTrait.selectWeaponVersus(e,t,this.game,!1,!0))&&i.name!==e.armedTrait?.deathWeapon?.name&&(!i.rules.limboLaunch||!i.warhead.rules.parasite)&&!i.warhead.rules.mindControl)return i}findRelocationTile(a,n,o){let l=this.game.map,i;if(o.rules.movementZone===MovementZone.Fly){var t=e=>!l.tileOccupation.getGroundObjectsOnTile(e).some(e=>e.isBuilding()&&!e.isDestroyed||e.isTerrain()||e.isOverlay()&&e.rules.isARock)&&(o.rules.locomotor!==LocomotorType.Jumpjet||0<this.game.map.terrain.getPassableSpeed(e,SpeedType.Amphibious,o.isInfantry(),!!e.onBridgeLandType));let e=new RandomTileFinder(l.tiles,l.mapBounds,a,1,this.game,t);if(i=e.getNextTile(),!i){let e=new RadialTileFinder(l.tiles,l.mapBounds,a,o.getFoundation(),2,15,t);i=e.getNextTile()}}else{let e=!this.options?.ignoredBlockers?.length&&l.terrain.getPassableSpeed(o.tile,o.rules.speedType,o.isInfantry(),o.onBridge)?this.game.map.terrain.getIslandIdMap(o.rules.speedType,o.isInfantry()):void 0,r=e?.get(o.tile,o.onBridge),s=new MovePositionHelper(l),t=new RadialTileFinder(l.tiles,l.mapBounds,a,{width:1,height:1},0,5,t=>{let i=!n||n.isHighBridge()?l.tileOccupation.getBridgeOnTile(t):void 0;return!this.unreachableTargets.find(e=>e.tile===t&&e.toBridge===!!i)&&(o.zone===ZoneType.Air||e?.get(t,!!i)===r&&!l.terrain.findObstacles({tile:t,onBridge:i},o).length&&s.isEligibleTile(t,i,n,a))&&this.canStopAtTile(o,t,!!i)});i=t.getNextTile()}return i}findFreeSubCell(t,i){let e=this.game.map.getGroundObjectsOnTile(i.tile);var r=e.filter(e=>e.isInfantry()&&e.onBridge===!!i.onBridge&&e!==t).map(e=>e.position.desiredSubCell),s=e.filter(e=>e.isTerrain()).map(e=>e.rules.getOccupiedSubCells(this.game.map.getTheaterType())).flat();let a=[...r,...s];return Infantry_Infantry.SUB_CELLS.find(e=>-1===a.indexOf(e))}relocateToSubCell(e,t){e.position.desiredSubCell=t;t=e.position.computeSubCellOffset(t);this.targetOffset=t,this.currentWaypointLeptons.set(e.moveTrait.currentWaypoint.tile.rx,e.moveTrait.currentWaypoint.tile.ry).multiplyScalar(Coords.LEPTONS_PER_TILE).add(this.targetOffset),this.updateDestination(this.path,this.targetOffset),e.moveTrait.locomotor.onWaypointUpdate?.(e,this.currentWaypointLeptons,this.destinationLeptons)}getTargetLinesConfig(e){var t,i;return this.path||(t=new LocomotorFactory(this.game).create(e),(this.options?.allowOutOfBoundsTarget||this.game.map.mapBounds.isWithinBounds(this.targetTile))&&e.rules.movementZone!==MovementZone.Fly&&!t.ignoresTerrain&&e.unitOrderTrait.getCurrentTask()?.isCancelling()?this.groundPathPlan||(i=this.computeGroundPath(e),this.targetLinesConfig.pathNodes=i.path,i.path.length&&(this.groundPathPlan=i)):((i=e.moveTrait).locomotor??(i.locomotor=t),this.computePath(e,e.moveTrait.locomotor)),this.targetLinesConfig.isRecalc=!1),this.targetLinesConfig}log(e,t){this.logger.debug(`<${e.id}>: `+t)}}(NotifyDestroy=NotifyDestroy||{}).onDestroy=Symbol(),function(e){e[e.None=0]="None",e[e.Normal=1]="Normal",e[e.Demolish=2]="Demolish",e[e.Crush=3]="Crush",e[e.Temporal=4]="Temporal",e[e.Sink=5]="Sink"}(DeathType=DeathType||{}),(NotifyTileChange=NotifyTileChange||{}).onTileChange=Symbol(),(NotifyTileChange_NotifyTileChange=NotifyTileChange_NotifyTileChange||{}).onTileChange=Symbol();class EnterTileEvent{constructor(e,t){this.target=e,this.source=t,this.type=EventType.EnterTile}}(NotifyElevationChange=NotifyElevationChange||{}).onElevationChange=Symbol(),function(e){e[e.Idle=0]="Idle",e[e.ReachedNextWaypoint=1]="ReachedNextWaypoint",e[e.PlanMove=2]="PlanMove",e[e.Moving=3]="Moving"}(MoveState=MoveState||{}),function(e){e[e.Success=0]="Success",e[e.Cancel=1]="Cancel",e[e.CloseEnough=2]="CloseEnough",e[e.Fail=3]="Fail"}(MoveResult=MoveResult||{}),function(e){e[e.Waiting=0]="Waiting",e[e.Resolved=1]="Resolved"}(CollisionState=CollisionState||{});const findMoveTaskDeep=e=>e instanceof MoveTask||e.children[0]&&findMoveTaskDeep(e.children[0]);class MoveTrait{get baseSpeed(){return this.gameObject.rules.speed*(this.gameObject.veteranTrait?.getVeteranSpeedMultiplier()??1)*this.gameObject.crateBonuses.speed*(this.gameObject.isVehicle()&&this.gameObject.healthTrait.health<=50&&this.gameObject.rules.locomotor!==LocomotorType.Hover?.75:1)*(1-this.speedPenalty)}constructor(e,t){this.gameObject=e,this.tileOccupation=t,this.disabled=!1,this.speedPenalty=0,this.velocity=new Vector3_Vector3,this.reservedPathNodes=[],this.moveState=MoveState.Idle,this.collisionState=CollisionState.Resolved}isDisabled(){return this.disabled}setDisabled(e){this.disabled=e}isMoving(){return this.moveState===MoveState.Moving}isIdle(){return this.moveState===MoveState.Idle}isWaiting(){return this.collisionState===CollisionState.Waiting}[NotifyTick_NotifyTick.onTick](e,t){var i;this.moveState!==MoveState.Idle&&this.collisionState===CollisionState.Resolved&&((i=e.unitOrderTrait.getCurrentTask())&&findMoveTaskDeep(i)||(this.velocity.set(0,0,0),this.moveState=MoveState.Idle,this.locomotor=void 0,!i&&!e.attackTrait?.currentTarget&&e.isVehicle()&&e.turretTrait&&(e.turretTrait.desiredFacing=e.direction))),this.moveState===MoveState.Idle&&(e.rules.locomotor===LocomotorType.Jumpjet?JumpjetLocomotor.tickStationary(e,t):e.isAircraft()&&e.rules.locomotor===LocomotorType.Aircraft&&WingedLocomotor.tickStationary(e,t))}[NotifyDestroy.onDestroy](e,t){this.unreservePathNodes()}teleportUnitToTile(e,t,i,r,s){let a=this.gameObject;var n=a.tile;a.traits.filter(NotifyTeleport).forEach(e=>{e[NotifyTeleport.onBeforeTeleport](a,s,i,r)}),a.position.tileElevation=a.tileElevation,a.position.tile=e,a.position.subCell=a.position.desiredSubCell,this.handleTileChange(n,t,!0,s,!0),r||(this.unreservePathNodes(),this.speedPenalty=0,this.velocity.set(0,0,0),this.moveState=MoveState.Idle,this.collisionState=CollisionState.Resolved,this.locomotor=void 0,this.currentWaypoint=void 0,this.lastTargetOffset=void 0,this.lastVelocity=void 0,this.lastMoveResult=MoveResult.Cancel,a.isVehicle()&&(a.spinVelocity=0,a.turretTrait&&(a.turretTrait.desiredFacing=a.direction))),this.lastTeleportTick=s.currentTick,s.events.dispatch(new ObjectTeleportEvent(a,i,n))}handleTileChange(t,e,i,r,s=!1){const a=this.gameObject;if(r.map.tileOccupation.unoccupyTileRange(t,a),r.map.tileOccupation.occupyTileRange(a.tile,a),r.map.technosByTile.updateObject(a),a.zone!==ZoneType.Air){var n=a.onBridge?r.map.tileOccupation.getBridgeOnTile(t):void 0,o=a.onBridge?t.onBridgeLandType:t.landType,l=e?a.tile.onBridgeLandType:a.tile.landType;o!==l&&(0<r.rules.getLandRules(l).getSpeedModifier(a.rules.speedType)||a.rules.speedType===SpeedType.Amphibious||s)&&(a.zone=getZoneType(l)),e!==n&&(a.position.tileElevation+=-(n?.tileElevation??0)+(e?.tileElevation??0),a.onBridge=!!e);var h,e=a.moveTrait.reservedPathNodes.findIndex(e=>e.tile===a.tile);if(-1!==e&&a.moveTrait.reservedPathNodes.splice(e,1),a.crusher)for(h of r.map.getGroundObjectsOnTile(a.tile).filter(e=>(!e.isUnit()||e.onBridge===a.onBridge)&&e.rules.crushable&&!(e.isInfantry()&&e.stance===StanceType.Paradrop)&&(!(e.isTechno()&&!i)||!r.areFriendly(e,a))))h.isDestroyed||(h.isInfantry()&&(h.infDeathType=InfDeathType.None),a.isVehicle()&&h.isOverlay()&&h.rules.wall&&a.applyRocking(0,.5),h.deathType=DeathType.Crush,r.destroyObject(h,{player:a.owner,obj:a}));a.onBridge||(e=r.map.tileOccupation.getGroundObjectsOnTile(a.tile).find(e=>e.isOverlay()&&e.rules.crate))&&r.crateGeneratorTrait.pickupCrate(a,e,r)}r.traits.filter(NotifyTileChange).forEach(e=>{e[NotifyTileChange.onTileChange](a,r,t,s)}),a.traits.filter(NotifyTileChange_NotifyTileChange).forEach(e=>{e[NotifyTileChange_NotifyTileChange.onTileChange](a,r,t,s)}),r.events.dispatch(new EnterTileEvent(a.tile,a))}handleElevationChange(t,i){i.traits.filter(NotifyElevationChange).forEach(e=>{e[NotifyElevationChange.onElevationChange](this.gameObject,i,t)})}unreservePathNodes(){this.reservedPathNodes.forEach(e=>{e.tile!==this.gameObject.tile&&this.tileOccupation.unoccupySingleTile(e.tile,this.gameObject)}),this.reservedPathNodes.length=0}dispose(){this.gameObject=void 0}}class SuppressionTrait{constructor(){this.suppressionTicks=0,this.enabled=!0}disable(){this.enabled=!1}isSuppressed(){return this.enabled&&0<this.suppressionTicks}suppress(){this.enabled&&(this.suppressionTicks=30)}[NotifyTick_NotifyTick.onTick](){0<this.suppressionTicks&&this.suppressionTicks--}}class Traits{constructor(){this.allTraits=[],this.traitsByTypeCache=new Map}add(e){this.allTraits.push(e),this.traitsByTypeCache.clear()}addToFront(e){this.allTraits.unshift(e),this.traitsByTypeCache.clear()}remove(e){e=this.allTraits.indexOf(e);-1!==e&&(this.allTraits.splice(e,1),this.traitsByTypeCache.clear())}filter(t){let e=this.traitsByTypeCache.get(t);return e||(e="function"==typeof t?this.allTraits.filter(e=>e instanceof t):this.allTraits.filter(e=>this.traitImplements(e,t)),this.traitsByTypeCache.set(t,e)),e}get(e){e=this.find(e);if(!e)throw new Error("No matching trait found");return e}find(e){return this.filter(e)[0]}getAll(){return this.allTraits}traitImplements(e,t){for(var i of Object.getOwnPropertyNames(t))if(void 0===e[t[i]])return!1;return!0}clear(){this.allTraits.length=0,this.traitsByTypeCache.clear()}dispose(){this.getAll().forEach(e=>e.dispose?.()),this.clear()}}(NotifyOwnerChange=NotifyOwnerChange||{}).onChange=Symbol(),(NotifySpawn=NotifySpawn||{}).onSpawn=Symbol(),(NotifyUnspawn=NotifyUnspawn||{}).onUnspawn=Symbol(),(NotifyAttack=NotifyAttack||{}).onAttack=Symbol();class GameObject{get tile(){return this.position.tile}get tileElevation(){return this.position.tileElevation}constructor(e,t,i,r){this.traits=new Traits,this.cachedTraits={tick:[]},this.isCrashing=!1,this.isDestroyed=!1,this.deathType=DeathType.Normal,this.isDisposed=!1,this.isSpawned=!1,this.type=e,this.name=t,this.rules=i,this.art=r}getFoundation(){return{width:1,height:1}}isSmudge(){return this.type===ObjectType.Smudge}isOverlay(){return this.type===ObjectType.Overlay}isTerrain(){return this.type===ObjectType.Terrain}isProjectile(){return this.type===ObjectType.Projectile}isDebris(){return this.type===ObjectType.Debris}isBuilding(){return!1}isInfantry(){return!1}isVehicle(){return!1}isAircraft(){return!1}isUnit(){return!1}isTechno(){return!1}update(e){for(var t of this.cachedTraits.tick)t[NotifyTick_NotifyTick.onTick](this,e)}onSpawn(t){this.isSpawned=!0,this.traits.filter(NotifySpawn).forEach(e=>{e[NotifySpawn.onSpawn](this,t)})}onUnspawn(t){this.isSpawned=!1,this.traits.filter(NotifyUnspawn).forEach(e=>{e[NotifyUnspawn.onUnspawn](this,t)})}onDestroy(t,i,r){this.traits.filter(NotifyDestroy).forEach(e=>{e[NotifyDestroy.onDestroy](this,t,i,r)})}onOwnerChange(t,i){this.traits.filter(NotifyOwnerChange).forEach(e=>{e[NotifyOwnerChange.onChange](this,t,i)})}onAttack(t,i){this.traits.filter(NotifyAttack).forEach(e=>{e[NotifyAttack.onAttack](this,i,t)})}addTrait(e){this.traits.add(e),e[NotifyTick_NotifyTick.onTick]&&this.cachedTraits.tick.push(e)}getUiName(){return this.rules.uiName}getHash(){var e=this.position.worldPosition;return fnv32a([this.id,...new Uint8Array(new Float64Array([e.x||0,e.y||0,e.z||0]).buffer),...this.traits.getAll().map(e=>e.getHash?.()??0)])}debugGetState(){return{id:this.id,position:this.position.worldPosition.toArray(),traits:this.traits.getAll().reduce((e,t)=>{var i=t.debugGetState?.();return void 0!==i&&(e[t.constructor.name]=i),e},{})}}dispose(){this.isDisposed=!0,this.traits.dispose(),this.cachedTraits.tick.length=0}}!function(e){e[e.None=0]="None",e[e.Veteran=1]="Veteran",e[e.Elite=2]="Elite"}(VeteranLevel=VeteranLevel||{});class Techno_Techno extends GameObject{get primaryWeapon(){return this.armedTrait?.primaryWeapon}get secondaryWeapon(){return this.armedTrait?.secondaryWeapon}get ammo(){return this.ammoTrait?.ammo}get sight(){return Math.min(TechnoRules.MAX_SIGHT,this.rules.sight*(this.veteranTrait?.getVeteranSightMultiplier()??1))}get veteranLevel(){return this.veteranTrait?.veteranLevel??VeteranLevel.None}constructor(e,t,i,r){super(e,t,i,r),this.explodes=this.rules.explodes,this.radarInvisible=this.rules.radarInvisible,this.c4=this.rules.c4,this.crusher=this.rules.crusher,this.defaultToGuardArea=this.rules.defaultToGuardArea,this.guardMode=this.rules.defaultToGuardArea,this.purchaseValue=this.rules.cost}resetGuardModeToIdle(){this.guardMode=this.defaultToGuardArea,this.guardArea=void 0}update(e){if(this.warpedOutTrait.isActive())for(var t of this.cachedTraits.tick)t.ticksWhenWarpedOut&&t[NotifyTick_NotifyTick.onTick](this,e);else super.update(e)}isTechno(){return!0}}class IdleActionTrait{constructor(){this.cooldownTicks=Number.POSITIVE_INFINITY,this._actionDueThisTick=!1}[NotifyTick_NotifyTick.onTick](e,t){this._actionDueThisTick=!1;var i=!e.unitOrderTrait.hasTasks();i&&!this.idle?this.resetCooldown(t):i?0===this.cooldownTicks?(this.doIdleAction(e,t),this.resetCooldown(t)):this.cooldownTicks--:this.cooldownTicks=Number.POSITIVE_INFINITY,this.idle=i}doIdleAction(e,t){if(e.isInfantry()){if(e.rules.fraidycat)if(e.owner.isNeutral&&.5<t.generateRandom())return void e.unitOrderTrait.addTask(new ScatterTask(t,void 0,{noSlopes:!0}));this._actionDueThisTick=!0}}actionDueThisTick(){return this._actionDueThisTick}resetCooldown(e){var t=e.rules.audioVisual.idleActionFrequency,e=e.generateRandom()*t*.5,e=Math.max(0,t-e);this.cooldownTicks=Math.floor(e*GameSpeed.BASE_TICKS_PER_SECOND)}}class ObjectCrashingEvent{constructor(e){this.gameObject=e,this.type=EventType.ObjectCrashing}}(NotifyCrash=NotifyCrash||{}).onCrash=Symbol();class CrashableTrait{constructor(e){this.gameObject=e,this.crashingEvtSent=!1,this.crashState={}}[NotifyTick_NotifyTick.onTick](i,r){if(i.isCrashing){if(this.crashingEvtSent||(this.crashingEvtSent=!0,i.traits.filter(NotifyCrash).forEach(e=>e[NotifyCrash.onCrash](i,r)),r.events.dispatch(new ObjectCrashingEvent(i))),i.rules.locomotor!==LocomotorType.Jumpjet&&i.rules.locomotor!==LocomotorType.Aircraft)throw new Error("Crashing logic not implemented for locomotor "+LocomotorType[i.rules.locomotor]);{let e;if(i.rules.locomotor===LocomotorType.Jumpjet)e=JumpjetLocomotor.tickCrash(i,r,this.crashState);else{if(i.rules.locomotor!==LocomotorType.Aircraft)throw new Error(`Unhandled locomotor type "${i.rules.locomotor}"`);if(!i.isAircraft())throw new Error(`Obj "${i.name}#${i.id} is not an aircraft`);e=WingedLocomotor.tickCrash(i,r,this.crashState)}let t=!1;var s,a,n=e.clone().add(i.position.worldPosition);r.map.isWithinHardBounds(n)?(a=i.tile,s=i.tileElevation,i.position.moveByLeptons3(e),i.tile!==a&&i.moveTrait.handleTileChange(a,void 0,!1,r),a=(n=i.tile.onBridgeLandType?r.map.tileOccupation.getBridgeOnTile(i.tile):void 0)?.tileElevation??0,i.position.tileElevation=Math.max(i.position.tileElevation,a),i.position.tileElevation===a&&(i.zone=r.map.getTileZone(i.tile),i.onBridge=!!n,t=!0),i.tileElevation!==s&&i.moveTrait.handleElevationChange(s,r)):t=!0,t&&r.destroyObject(i,this.attackerInfo)}}}crash(e){this.attackerInfo=e,this.gameObject.isCrashing=!0,this.gameObject.cachedTraits.tick.length=0,this.gameObject.cachedTraits.tick=[this]}dispose(){this.gameObject=void 0}}class AgentTrait{infiltrate(e,t,i){var r;t.rules.radar&&![...t.owner.buildings].some(e=>e.rules.spySat)&&i.mapShroudTrait.resetShroud(t.owner,i),0<t.rules.power&&(r=i.rules.general.spyPowerBlackout,t.owner.powerTrait?.setBlackoutFor(r,i)),t.superWeaponTrait&&t.superWeaponTrait.getSuperWeapon(t)?.resetTimer(),0<t.rules.storage&&(r=clamp(i.rules.general.spyMoneyStealPercent,0,1),r=Math.floor(t.owner.credits*r),t.owner.credits-=r,e.owner.credits+=r),!i.rules.ai.buildTech.includes(t.name)||void 0!==(i=t.rules.aiBasePlanningSide)&&e.owner.production.addStolenTech(i),t.factoryTrait&&[FactoryType.InfantryType,FactoryType.UnitType].includes(t.factoryTrait.type)&&e.owner.production?.addVeteranType(t.factoryTrait.type)}}class CrateBonuses{constructor(){this.firepower=1,this.armor=1,this.speed=1}}class Infantry_Infantry extends Techno_Techno{get isMoving(){return this.moveTrait.isMoving()}static factory(e,t,i,r){let s=new this(e,t,i);return s.moveTrait=new MoveTrait(s,r),s.traits.add(s.moveTrait),s.rules.crashable&&(s.crashableTrait=new CrashableTrait(s),s.traits.add(s.crashableTrait)),s.rules.fearless||(s.suppressionTrait=new SuppressionTrait,s.traits.add(s.suppressionTrait)),s.rules.agent&&(s.agentTrait=new AgentTrait,s.traits.add(s.agentTrait)),s.idleActionTrait=new IdleActionTrait,s.traits.add(s.idleActionTrait),s}constructor(e,t,i){super(ObjectType.Infantry,e,t,i),this.direction=0,this.onBridge=!1,this.zone=ZoneType.Ground,this._stance=StanceType.None,this.isFiring=!1,this.isPanicked=!1,this.infDeathType=InfDeathType.Gunfire,this.crateBonuses=new CrateBonuses}get stance(){return this._stance===StanceType.None&&this.suppressionTrait?.isSuppressed()?StanceType.Prone:this._stance}set stance(e){this._stance=e,this.moveTrait.setDisabled([StanceType.Deployed,StanceType.Cheer].includes(e)),this.attackTrait?.setDisabled([StanceType.Paradrop,StanceType.Cheer].includes(e))}isUnit(){return!0}isInfantry(){return!0}}Infantry_Infantry.SUB_CELLS=[2,4,3];class ParadropTask extends Task{constructor(e){super(),this.game=e}onTick(e){var t=Math.abs(this.game.rules.general.parachuteMaxFallRate),i=e.tile.onBridgeLandType?this.game.map.tileOccupation.getBridgeOnTile(e.tile).tileElevation:0,r=Coords.tileHeightToWorld(i),s=e.tileElevation,a=Coords.tileHeightToWorld(s);return r<Math.max(r,a-t)?(e.position.moveByLeptons3(new Vector3_Vector3(0,-t,0)),e.moveTrait.handleElevationChange(s,this.game),!1):(e.position.tileElevation=i,e.stance=StanceType.None,this.game.map.terrain.getPassableSpeed(e.tile,e.rules.speedType,e.isInfantry(),e.onBridge)||(e.infDeathType=InfDeathType.None,this.game.destroyObject(e,void 0,!0)),!0)}}function bresenham(i,r,s,a,n){let o=[];n=n||((e,t)=>{o.push({x:e,y:t})});var e=s-i,t=a-r,l=Math.abs(e),h=Math.abs(t);let c=0;var d=0<e?1:-1,u=0<t?1:-1;if(h<l)for(let e=i,t=r;d<0?e>=s:e<=s;e+=d)n(e,t),c+=h,c<<1>=l&&(t+=u,c-=l);else for(let e=i,t=r;u<0?t>=a:t<=a;t+=u)n(e,t),c+=l,c<<1>=h&&(e+=d,c-=h);return o}function isNotNullOrUndefined(e){return null!=e}class TaskGroup extends Task{constructor(...e){super(),this.children.push(...e)}onTick(e){return!0}}class UnlandableTrait{constructor(){this.enabled=!0}setEnabled(e){this.enabled=e}[NotifyTick_NotifyTick.onTick](e,t){var i;this.enabled&&(e.owner.isNeutral||e.name===t.rules.general.paradrop.paradropPlane)&&e.unitOrderTrait.isIdle()&&(i=this.chooseExitTile(e.tile,t),e.unitOrderTrait.addTask(new TaskGroup(new MoveTask(t,i,!1,{allowOutOfBoundsTarget:!0}),new CallbackTask(e=>t.unspawnObject(e))).setCancellable(!1)))}chooseExitTile(e,t){var i=t.map.tiles.getMapSize(),i=.5<t.generateRandom()?new Vector2(Math.floor(i.width/2),0):new Vector2(0,Math.floor(i.height/2)),e=new Vector2(e.rx,e.ry),i=bresenham(e.x,e.y,i.x,i.y).map(e=>t.map.tiles.getByMapCoords(e.x,e.y)).filter(isNotNullOrUndefined);if(!i.length)throw new Error("No valid exit tile found");return i[i.length-1]}}!function(e){e[e.Spawning=0]="Spawning",e[e.EnRoute=1]="EnRoute",e[e.Dropping=2]="Dropping",e[e.TurningAround=3]="TurningAround"}(ParadropState=ParadropState||{});const PLANE_SPAWN_DELAY_FRAMES=5*GameSpeed.BASE_TICKS_PER_SECOND,MAX_FAILED_ATTEMPTS=5;class ParadropEffect extends SuperWeaponEffect{constructor(e,t,i,r,s){super(e,t,i),this.paradropSquad=r,this.state=ParadropState.Spawning,this.failedAttempts=0,this.spawnDelay=s*PLANE_SPAWN_DELAY_FRAMES}onStart(e){this.passengerRules=e.rules.getObject(this.paradropSquad.inf,ObjectType.Infantry),this.passengerCount=this.paradropSquad.num}computeFlightPath(e,t,i){if(t.equals(e))throw new Error("Source and destination must be different");let r=e.clone().sub(t);e=i.rules.general.paradrop.paradropRadius/Coords.LEPTONS_PER_TILE,e=t.clone().add(r.clone().setLength(r.length()+2*e)).floor();let s=bresenham(t.x,t.y,e.x,e.y).map(e=>i.map.tiles.getByMapCoords(e.x,e.y)??i.map.tiles.getPlaceholderTile(e.x,e.y));for(;s.length;){var a=s[0],a=Coords.tileToWorld(a.rx+.5,a.ry+.5);if(i.map.isWithinHardBounds(new Vector2(a.x,a.y)))break;s.shift()}if(!s.length)throw new Error("No valid paradrop path found");return{fromTile:s[0],toTile:s[s.length-1]}}onTick(s){if(this.state===ParadropState.Spawning){if(0<this.spawnDelay)return this.spawnDelay--,!1;var a=s.map.tiles.getMapSize(),n=[new Vector2(0,0),new Vector2(Math.floor(a.width/2),0),new Vector2(0,Math.floor(a.height/2))][s.generateRandomInt(0,2)];let t=this.passengerRules.speedType,e=new RadialTileFinder(s.map.tiles,s.map.mapBounds,this.tile,{width:1,height:1},0,50,e=>0<s.map.terrain.getPassableSpeed(e,t,!0,!!e.onBridgeLandType));var o=this.targetTile=e.getNextTile();if(!o)return!0;let i=new Vector2(o.rx,o.ry);var{fromTile:l,toTile:a}=this.computeFlightPath(i,n,s),o=s.rules.general.paradrop.paradropPlane,n=s.rules.getObject(o,ObjectType.Aircraft);let r=this.pdPlane=s.createUnitForPlayer(n,this.owner);s.spawnObject(r,l),r.direction=FacingUtil.fromMapCoords(i.clone().sub(new Vector2(l.rx,l.ry))),r.position.tileElevation=Coords.worldToTileHeight(r.rules.flightLevel??s.rules.general.flightLevel),r.zone=ZoneType.Air,r.onBridge=!1,r.unitOrderTrait.addTask(new MoveTask(s,a,!1,{allowOutOfBoundsTarget:!0})),r.traits.get(UnlandableTrait).setEnabled(!1),this.state=ParadropState.EnRoute}if(!this.pdPlane||this.pdPlane.isDestroyed||this.pdPlane.isCrashing)return!0;o=this.targetTile;if(!this.pdPlane.unitOrderTrait.hasTasks())return this.state=ParadropState.TurningAround,this.pdPlane.unitOrderTrait.addTask(new MoveTask(s,o,!1,{allowOutOfBoundsTarget:!0})),!1;n=s.rules.general.paradrop.paradropRadius/Coords.LEPTONS_PER_TILE;let e=new RangeHelper(s.map.tileOccupation);l=e.isInTileRange(this.pdPlane.tile,o,0,n);if(this.state===ParadropState.EnRoute&&l&&(this.state=ParadropState.Dropping),this.state===ParadropState.Dropping)if(l&&0<this.passengerCount){a=this.pdPlane.tile;let t=!!a.onBridgeLandType;if(this.failedAttempts>MAX_FAILED_ATTEMPTS&&s.map.mapBounds.isWithinBounds(a))return this.passengerCount=0,!1;if(!s.map.terrain.getPassableSpeed(a,this.passengerRules.speedType,!0,t))return!1;let e=s.map.getGroundObjectsOnTile(a);if(e.some(e=>e.isVehicle()&&e.onBridge===t||e.isBuilding()&&!e.isDestroyed||e.isInfantry()&&e.stance===StanceType.Paradrop))return!1;n=this.findFreeSubCell(s,a);if(!n)return!1;this.passengerCount--;let i=s.createUnitForPlayer(this.passengerRules,this.owner);i.stance=StanceType.Paradrop,i.position.tileElevation=this.pdPlane.tileElevation,i.position.subCell=n,i.onBridge=t,i.rules.trainable&&this.owner.canProduceVeteran(i.rules)&&i.veteranTrait?.setVeteranLevel(VeteranLevel.Veteran),s.spawnObject(i,a),i.unitOrderTrait.addTask(new ParadropTask(s).setCancellable(!1))}else{if(!(0<this.passengerCount))return this.pdPlane.unitOrderTrait.getCurrentTask().forceCancel(this.pdPlane),this.pdPlane.traits.get(UnlandableTrait).setEnabled(!0),!0;this.failedAttempts++,this.state=ParadropState.TurningAround,this.pdPlane.unitOrderTrait.getCurrentTask().updateTarget(o,!!o.onBridgeLandType)}return this.state===ParadropState.TurningAround&&l&&(o=this.computeFlightPath(new Vector2(o.rx,o.ry),new Vector2(this.pdPlane.tile.rx,this.pdPlane.tile.ry),s)["toTile"],this.pdPlane.unitOrderTrait.getCurrentTask().updateTarget(o,!1),this.state=ParadropState.EnRoute),!1}findFreeSubCell(t,e){let i=t.map.getGroundObjectsOnTile(e).filter(e=>e.isTerrain()).map(e=>e.rules.getOccupiedSubCells(t.map.getTheaterType())).flat();e=Infantry_Infantry.SUB_CELLS.filter(e=>-1===i.indexOf(e));if(e.length)return 1<e.length?e[t.generateRandomInt(0,e.length-1)]:e[0]}}!function(e){e[e.NotBridge=0]="NotBridge",e[e.Concrete=1]="Concrete",e[e.Wood=2]="Wood"}(OverlayBridgeType=OverlayBridgeType||{});class BridgeOverlayTypes{static getOverlayBridgeType(e){return isBetween(e,this.minHighBridgeConcreteId,this.maxHighBridgeConcreteId)||isBetween(e,this.minLowBridgeConcreteId,this.maxLowBridgeConcreteId)?OverlayBridgeType.Concrete:isBetween(e,this.minHighBridgeWoodId,this.maxHighBridgeWoodId)||isBetween(e,this.minLowBridgeWoodId,this.maxLowBridgeWoodId)?OverlayBridgeType.Wood:OverlayBridgeType.NotBridge}static isBridge(e){return this.isHighBridge(e)||this.isLowBridge(e)}static isBridgePlaceholder(e){return this.bridgePlaceholderIds.includes(e)}static isHighBridge(e){return isBetween(e,this.minHighBridgeWoodId,this.maxHighBridgeWoodId)||isBetween(e,this.minHighBridgeConcreteId,this.maxHighBridgeConcreteId)}static isLowBridge(e){return isBetween(e,this.minLowBridgeWoodId,this.maxLowBridgeWoodId)||isBetween(e,this.minLowBridgeConcreteId,this.maxLowBridgeConcreteId)}static isXBridge(e){return e===this.minHighBridgeWoodId||e===this.minHighBridgeConcreteId||isBetween(e,this.minLowBridgeWoodId,this.minLowBridgeWoodId+8)||isBetween(e,this.minLowBridgeWoodId+18,this.minLowBridgeWoodId+21)||isBetween(e,this.minLowBridgeConcreteId,this.minLowBridgeConcreteId+8)||isBetween(e,this.minLowBridgeConcreteId+18,this.minLowBridgeConcreteId+21)}static isLowBridgeHead(e){return isBetween(e,this.minLowBridgeWoodId+18,this.minLowBridgeWoodId+25)||isBetween(e,this.minLowBridgeConcreteId+18,this.minLowBridgeConcreteId+25)}static isLowBridgeHeadStart(e){return isBetween(e,this.minLowBridgeWoodId+20,this.minLowBridgeWoodId+23)||isBetween(e,this.minLowBridgeConcreteId+20,this.minLowBridgeConcreteId+23)}static calculateLowBridgeOverlayId(e,t){let i;if(e===OverlayBridgeType.Concrete)i=this.minLowBridgeConcreteId;else{if(e!==OverlayBridgeType.Wood)throw new Error("Not implemented");i=this.minLowBridgeWoodId}return i+(t?0:9)}static calculateHighBridgeOverlayId(e,t){let i;if(e===OverlayBridgeType.Concrete)i=this.minHighBridgeConcreteId;else{if(e!==OverlayBridgeType.Wood)throw new Error("Not implemented");i=this.minHighBridgeWoodId}return i+(t?0:1)}}BridgeOverlayTypes.minLowBridgeWoodId=74,BridgeOverlayTypes.maxLowBridgeWoodId=99,BridgeOverlayTypes.minLowBridgeConcreteId=205,BridgeOverlayTypes.maxLowBridgeConcreteId=230,BridgeOverlayTypes.minHighBridgeConcreteId=24,BridgeOverlayTypes.maxHighBridgeConcreteId=25,BridgeOverlayTypes.minHighBridgeWoodId=237,BridgeOverlayTypes.maxHighBridgeWoodId=238,BridgeOverlayTypes.bridgePlaceholderIds=[100,101,231,232],(NotifyAttack_NotifyAttack=NotifyAttack_NotifyAttack||{}).onAttack=Symbol(),function(e){e[e.None=0]="None",e[e.Ground=1]="Ground",e[e.Wall=2]="Wall",e[e.Cliff=3]="Cliff",e[e.OnBridge=4]="OnBridge",e[e.UnderBridge=5]="UnderBridge",e[e.Shore=6]="Shore"}(CollisionType=CollisionType||{});class WarheadDetonateEvent{constructor(e,t,i,r){this.target=e,this.position=t,this.explodeAnim=i,this.isLightningStrike=r,this.type=EventType.WarheadDetonate}}!function(e){e[e.Top=0]="Top",e[e.TopLeft=1]="TopLeft",e[e.TopRight=2]="TopRight",e[e.Left=3]="Left",e[e.Right=4]="Right",e[e.BottomLeft=5]="BottomLeft",e[e.Bottom=6]="Bottom",e[e.BottomRight=7]="BottomRight"}(TileDirection=TileDirection||{});class TileCollection{constructor(i,r,e,s){this.tileSets=r,this.generalRules=e;let a=this.rSize={width:0,height:0},n=this.dSize={width:0,height:0};for(let e=0,t=i.length;e<t;++e)a.width=Math.max(a.width,i[e].rx),a.height=Math.max(a.height,i[e].ry),n.width=Math.max(n.width,i[e].dx),n.height=Math.max(n.height,i[e].dy);a.width++,a.height++,n.width++,n.height++;let o=this.tilesByRxy=new Array(a.width*a.height);o.fill(void 0);let l=this.tilesByDxy=new Array(n.width*n.height);l.fill(void 0);let h=this.tiles=new Array(i.length),c=[],d=this.bridgeSetTiles=[],u=new Set(Object.values(TerrainType));this.minTileHeight=Number.POSITIVE_INFINITY;for(let e=this.maxTileHeight=0,t=i.length;e<t;++e){var p=i[e],g=r.getTileImage(p.tileNum,p.subTile,s),m=g.terrainType;if(!u.has(m))throw new Error(`Tile (${p.rx}, ${p.ry}) has unknown terrain type "${m}"`);var y={...p,terrainType:m,landType:getLandType(m),onBridgeLandType:void 0,rampType:g.rampType,id:p.rx+"_"+p.ry,occluded:!1},T=y.rx,f=y.ry,v=y.dx,m=y.dy;h[e]=y,o[T+f*a.width]=y,l[v+m*n.width]=y,this.minTileHeight=Math.min(this.minTileHeight,y.z),this.maxTileHeight=Math.max(this.maxTileHeight,y.z),4!==g.height||y.terrainType!==TerrainType.Cliff&&!r.isCliffTile(y.tileNum)||c.push(y),r.isHighBridgeBoundaryTile(p.tileNum)&&d.push(y)}this.computeLandBehindCliffTiles(c),this.cutoffTileHeight=this.computeCutoffTileHeight()}computeLandBehindCliffTiles(t){if(!(this.generalRules.cliffBackImpassability<2)){let e=[[-2,-2],[-1,-1],[-1,1],[1,-1],[0,1],[1,0]];t.forEach(t=>{for(var[i,r]of e){let e=this.getByMapCoords(t.rx+i,t.ry+r);e&&4<=t.z-e.z&&e.terrainType!==TerrainType.Cliff&&e.terrainType!==TerrainType.Rough&&(e.landType=LandType.Rock)}})}}getTileRadarColor(e){let t=this.tileSets.getTileImage(e.tileNum,e.subTile,()=>0);return t.radarLeft.clone().multiplyScalar(.5)}getAll(){return[...this.tiles]}forEach(i){for(let e=0,t=this.tiles.length;e<t;++e)i(this.tiles[e],e)}reduce(t,e){let i=e;return this.forEach(e=>{i=t(i,e)}),i}getMinTileHeight(){return this.minTileHeight}getMaxTileHeight(){return this.maxTileHeight}getCutoffTileHeight(){return this.cutoffTileHeight}computeCutoffTileHeight(){var t=this.dSize.width-1;let i=this.dSize.height-1,r=0,s=!0;for(;s&&0<i;){for(let e=1;e<t-3;e++){var a=this.getByDisplayCoords(e,i);a&&(s=!1,a.z>r&&(r=a.z))}s&&i--}return r}getAllBridgeSetTiles(){return this.bridgeSetTiles}getAllNeighbourTiles(e){var t=e.rx,e=e.ry;return[this.getByMapCoords(t+1,e+1),this.getByMapCoords(t-1,e-1),this.getByMapCoords(t-1,e+1),this.getByMapCoords(t+1,e-1),this.getByMapCoords(t,e+1),this.getByMapCoords(t+1,e),this.getByMapCoords(t-1,e),this.getByMapCoords(t,e-1)].filter(isNotNullOrUndefined)}getNeighbourTile(e,t){var i=e.rx,r=e.ry;switch(t){case TileDirection.Bottom:return this.getByMapCoords(i+1,r+1);case TileDirection.Top:return this.getByMapCoords(i-1,r-1);case TileDirection.Left:return this.getByMapCoords(i-1,r+1);case TileDirection.Right:return this.getByMapCoords(i+1,r-1);case TileDirection.BottomLeft:return this.getByMapCoords(i,r+1);case TileDirection.BottomRight:return this.getByMapCoords(i+1,r);case TileDirection.TopLeft:return this.getByMapCoords(i-1,r);case TileDirection.TopRight:return this.getByMapCoords(i,r-1);default:throw new Error("Invalid direction")}}getByDisplayCoords(e,t){if(!(e>=this.dSize.width||t>=this.dSize.height))return this.tilesByDxy[e+t*this.dSize.width]}getByMapCoords(e,t){if(!(e>=this.rSize.width||t>=this.rSize.height))return this.tilesByRxy[e+t*this.rSize.width]}getMapSize(){return this.rSize}getDisplaySize(){return this.dSize}getInRectangle(e,t){let i,r,s,a;a=t?(i=e.rx,r=e.ry,s=t.width,t.height):(i=e.x,r=e.y,s=e.width,e.height);let n=[];for(let t=0;t<s;t++)for(let e=0;e<a;e++){var o=i+t,l=r+e,l=this.getByMapCoords(o,l);l&&n.push(l)}return n}getPlaceholderTile(e,t){var i=this.tiles[0],i=i.dx-i.rx+i.ry+1;return{rx:e,ry:t,dx:e-t+i-1,dy:e+t-i-1,z:0,id:e+"_"+t,landType:LandType.Rock,terrainType:TerrainType.Rock1,rampType:0,subTile:0,tileNum:0,occluded:!1,onBridgeLandType:void 0}}}class TiberiumTrait{static canBePlacedOn(e,t){return[LandType.Clear,LandType.Road,LandType.Rough].includes(e.landType)&&!t.getGroundObjectsOnTile(e).find(e=>!e.isSmudge()&&!e.isUnit())}constructor(e,t){this.gameObject=e,this.rules=t}getTiberiumType(){return this.rules.type}collectBail(){var e=this.getBailCount();if(e<=0)throw new Error("Attempted to collect an ore bail, but there are none left");return this.gameObject.value--,1<e?this.getTiberiumType():void 0}spawnBails(e){this.gameObject.value=Math.min(TiberiumTrait.maxBails,this.gameObject.value+e)}removeBails(e){this.gameObject.value=Math.max(-1,this.gameObject.value-e)}getBailCount(){return this.gameObject.value+1}dispose(){this.gameObject=void 0}}TiberiumTrait.maxBails=11;class AnimTerrainEffect{destroyOre(i,r,s){if(r.landType===LandType.Tiberium&&(s.art.hasObject(i,ObjectType.Animation)?s.art.getAnimation(i):void 0)?.crater){let t=s.map.getObjectsOnTile(r).find(e=>e.isOverlay()&&e.isTiberium());if(t){r=Math.ceil(TiberiumTrait.maxBails/2),r=i.startsWith("S_CLSN")?r:s.generateRandomInt(1,r);let e=t.traits.get(TiberiumTrait);e.removeBails(r),e.getBailCount()||s.unspawnObject(t)}}}spawnSmudges(e,s,a){if(s.landType===LandType.Clear&&0===s.rampType&&a.map.mapBounds.isWithinBounds(s)&&!a.map.getObjectsOnTile(s).find(e=>!e.isUnit())){e=a.art.hasObject(e,ObjectType.Animation)?a.art.getAnimation(e):void 0;if(e?.crater){let t=e?.forceBigCraters?2:1,i=e?.scorch,r=[TileDirection.Bottom,TileDirection.BottomLeft,TileDirection.BottomRight].every(e=>a.map.tiles.getNeighbourTile(s,e));e=[...a.rules.smudgeRules.values()].filter(e=>(e.crater&&e.width===t&&e.height===t||i&&e.burn)&&!((1<e.width||1<e.height)&&!r));e.length&&(e=e[a.generateRandomInt(0,e.length-1)].name,e=a.createObject(ObjectType.Smudge,e),a.spawnObject(e,s))}}}}class ObjectAttackedEvent{constructor(e,t,i){this.target=e,this.attacker=t,this.incidental=i,this.type=EventType.ObjectAttacked}}!function(e){e[e.None=0]="None",e[e.Shrapnel=1]="Shrapnel",e[e.LightningStrike=2]="LightningStrike",e[e.TntCharge=3]="TntCharge"}(SpecialWarheadType=SpecialWarheadType||{});const ROCKING_MAX_DMG=300;class Warhead{constructor(e){this.rules=e}canDamage(e,t,i){return!(!e.isSpawned||e.isDisposed||e.isDestroyed||e.isCrashing)&&(!(e.isTechno()&&e.warpedOutTrait.isInvulnerable()&&!this.rules.temporal)&&((!e.isUnit()||!e.moveTrait.reservedPathNodes.find(e=>e.tile===t))&&(!!e.healthTrait&&((!e.isUnit()||e.zone!==ZoneType.Air||i===ZoneType.Air)&&(!(!e.isUnit()&&i===ZoneType.Air)&&((!e.isBuilding()||!e.rules.invisibleInGame)&&(!((e.isTechno()||e.isTerrain())&&e.rules.immune&&!this.rules.temporal)&&(!(e.isTechno()&&!e.rules.warpable&&this.rules.temporal)&&(!(this.rules.radiation&&(!e.isUnit()||e.rules.immuneToRadiation))&&(!(this.rules.psychicDamage&&(!e.isUnit()||e.rules.immuneToPsionics))&&(!e.isOverlay()||!BridgeOverlayTypes.isLowBridgeHead(e.overlayId))))))))))))}computeDamage(e,t,i,r=!1){let s=e;if(0<e&&t.isTechno()&&t.invulnerableTrait.isActive())return 0;if(t.isAircraft()&&t.missileSpawnTrait&&t.zone!==ZoneType.Air)return 0;if(!i.gameOpts.destroyableBridges&&t.isOverlay()&&t.bridgeTrait)return 0;if(this.rules.radiation||this.rules.temporal||!t.isInfantry()||t.stance!==StanceType.Prone||(s*=this.rules.proneDamage),t.isTechno()||t.isOverlay()||t.isTerrain()){let e=t.isTerrain()?ArmorType.Wood:t.rules.armor;t.isOverlay()&&t.isBridge()&&((i=BridgeOverlayTypes.getOverlayBridgeType(t.overlayId))===OverlayBridgeType.Wood?e=ArmorType.Wood:i===OverlayBridgeType.Concrete&&(e=ArmorType.Concrete)),r&&t.isOverlay()&&(t.isBridge()||t.rules.wall)||(s*=this.rules.verses.get(e)),0<s&&t.isTechno()&&t.veteranTrait&&(s/=t.veteranTrait.getVeteranArmorMultiplier()),0<s&&t.isUnit()&&(s/=t.crateBonuses.armor)}return(t.isOverlay()||t.isBuilding())&&t.rules.wall&&(this.rules.wallAbsoluteDestroyer?s=Number.POSITIVE_INFINITY:this.rules.wall||this.rules.wood&&t.rules.armor===ArmorType.Wood||(s=0)),t.isOverlay()&&t.isBridge()&&(this.rules.wall||(s=0)),s=0<s?Math.floor(s):Math.ceil(s),s}inflictDamage(e,t,i,r,s=!1){let a=t.healthTrait;return e===Number.POSITIVE_INFINITY&&(e=a.getHitPoints()),a.inflictDamage(e,i,r),r.traits.filter(NotifyAttack_NotifyAttack).forEach(e=>{e[NotifyAttack_NotifyAttack.onAttack](t,i?.obj,r)}),t.onAttack(r,i),r.events.dispatch(new ObjectAttackedEvent(t,i,s)),t.isTechno()&&!this.rules.temporal&&this.supressOrScatterTarget(t,r),!a.health&&(t.isInfantry()&&(t.infDeathType=this.rules.infDeath),this.rules.temporal&&(t.deathType=DeathType.Temporal),t.isUnit()&&t.crashableTrait&&t.zone===ZoneType.Air&&!this.rules.temporal?t.crashableTrait.crash(i):r.destroyObject(t,i,void 0,s),!0)}supressOrScatterTarget(e,t){e.rules.fraidycat||e.isVehicle()&&!e.owner.isCombatant()&&e.rules.insignificant?e.unitOrderTrait.hasTasks()||(e.isInfantry()&&(e.isPanicked=!0),e.unitOrderTrait.addTask(new ScatterTask(t)),e.isInfantry()&&e.unitOrderTrait.addTask(new CallbackTask(()=>e.isPanicked=!1).setCancellable(!1))):e.isInfantry()&&(e.moveTrait.isIdle()||e.suppressionTrait?.isSuppressed())&&e.suppressionTrait?.suppress()}createDummyWeaponInfo(){return{minRange:0,range:0,speed:Number.POSITIVE_INFINITY,type:WeaponType.Primary,rules:new WeaponRules(new IniSection("Dummy")),projectileRules:new ProjectileRules(ObjectType.Projectile,new IniSection("Dummy")),warhead:this}}detonate(r,e,t,i,s,a,n,o,l,h=SpecialWarheadType.None,c,d,u=!1){var p,g,m,y,T,f=l?.weapon??this.createDummyWeaponInfo(),v=l?.obj,b=l?.player,w=h===SpecialWarheadType.Shrapnel,S=h===SpecialWarheadType.LightningStrike,A=d?d/Coords.LEPTONS_PER_TILE:this.rules.cellSpread,_=this.rules.percentAtMax;let O=new Set,E=new Map,C=new RangeHelper(r.map.tileOccupation),k=new RadialTileFinder(r.map.tiles,r.map.mapBounds,t,{width:1,height:1},0,Math.ceil(A),()=>!0,!1);for(;p=k.getNextTile();)for(g of r.map.getObjectsOnTile(p))if((!O.has(g)||g.isBuilding())&&(n!==CollisionType.UnderBridge||!g.isUnit()||!g.onBridge)&&!(v&&g.isTechno()&&g.rules.typeImmune&&g.owner===b&&g.name===v.name)&&(g!==v||v.rules.damageSelf)&&this.canDamage(g,p,a)&&(!g.isOverlay()||!(!n&&.1<Math.abs(g.tileElevation-i)||n===CollisionType.OnBridge&&!g.isBridge()))){let e=g.isBuilding()?p===t?0:C.distance3(p,s)/Coords.LEPTONS_PER_TILE:g.isTerrain()||g.isOverlay()?C.distance3(p,t)/Coords.LEPTONS_PER_TILE:C.distance3(g,s)/Coords.LEPTONS_PER_TILE;if(A&&g.isAircraft()&&g.zone===ZoneType.Air&&(e/=2),e<.001&&(e=0),!(w&&g.isInfantry()&&b)||g.owner!==b&&!r.alliances.areAllied(g.owner,b)){if(!A)if(g.isTerrain()){if(p!==t||!this.rules.wall)continue}else if(!w&&(p!==t||!g.isBuilding()&&g!==(o.obj||o.getBridge())))continue;A&&e>A||(O.add(g),E.set(g,g.isBuilding()?(E.get(g)||[]).concat(e):[e]))}}let P=!1,I;for(m of O)if(!m.isDestroyed&&!m.isCrashing){let i=this.computeDamage(e,m,r,S);if(0<e&&!this.rules.affectsAllies&&m.isTechno()&&b&&(r.alliances.areAllied(m.owner,b)||m.owner===b)&&(i=0),i)for(var B of E.get(m)){let t=i;if(0<A&&Number.isFinite(t)&&(t=lerp(t,_*t,B/A)),Math.abs(t)<1&&(!A||.25<=t/i)&&(t=+Math.sign(t)),t=0<t?Math.floor(t):Math.ceil(t),t){let e=m.healthTrait;if(t<0){if(!v)throw new Error("Expected healer object to be set");if(e.healBy(-t,v,r),100===e.health)break}else{if(m===o.obj&&B<1&&(I=m),this.rules.causesDelayKill&&m.isBuilding()&&m.delayedKillTrait&&(y=m.healthTrait.getHitPoints(),t>=y&&(t=y-1,m.delayedKillTrait.isActive()||(y=this.rules.delayKillAtMax,T=lerp(T=this.rules.delayKillFrames,y*T,B/A),m.delayedKillTrait.activate(T,l)))),this.inflictDamage(t,m,l,r,!I))break;m.isVehicle()&&this.rules.rocker&&(0<(B=clamp(i/ROCKING_MAX_DMG,0,1))&&(T=FacingUtil.fromMapCoords(m.position.getMapPosition().clone().sub(Coords.vecWorldToGround(s)))-m.direction,m.applyRocking(T,B)))}}}else m.isTechno()&&m.invulnerableTrait.isActive()&&(P=!0)}f=f.rules.radLevel;f&&A&&r.mapRadiationTrait.createRadSite(t,f,A+1);u=u?void 0:P?r.rules.audioVisual.weaponNullifyAnim:this.pickExplodeAnim(e,I,a,r,S);if(!P&&a===ZoneType.Ground){let e=new AnimTerrainEffect;u&&e.destroyOre(u,t,r),c&&e.spawnSmudges(c,t,r),u&&e.spawnSmudges(u,t,r)}r.events.dispatch(new WarheadDetonateEvent(this,s,u,S))}pickExplodeAnim(t,i,r,s,a){if(t){if(a)return s.rules.audioVisual.weatherConBoltExplosion;if(this.rules.conventional&&r===ZoneType.Water&&(!i||i.isBuilding()||i.isVehicle()&&i.submergibleTrait)){var n=s.rules.combatDamage.splashList;return n[clamp(Math.floor(t/50),0,n.length-1)]}n=this.rules.animList.length;let e;return n?(e=s.rules.combatDamage.c4Warhead===this.rules.name?n-1:this.rules.emEffect?s.generateRandomInt(0,n-1):clamp(Math.floor(t/25),0,n-1),this.rules.animList[e]):void 0}}}Warhead.SPECIAL_WARHEAD_NAME="Special",Warhead.HE_WARHEAD_NAME="HE";class FlhCoords{constructor(e){this.forward=0,this.lateral=0,this.vertical=0,e&&3===e.length&&this.fromArray(e)}fromArray(e){return this.forward=e[0],this.lateral=e[1],this.vertical=e[2],this}clone(){return new FlhCoords([this.forward,this.lateral,this.vertical])}}class WeaponFireEvent{constructor(e,t){this.weapon=e,this.gameObject=t,this.type=EventType.WeaponFire}}class WeaponTargeting{constructor(e,t,i,r,s,a){this.weaponType=e,this.projectileRules=t,this.weaponRules=i,this.warheadRules=r,this.gameObject=s,this.generalRules=a,this.targetChecks=[],this.initConditions()}initConditions(){this.projectileRules.isAntiGround||this.targetChecks.push(e=>!!e);const a=this.generalRules.prism.type;this.gameObject.name===a&&this.weaponType===WeaponType.Secondary?this.targetChecks.push((e,t,i,r,s)=>!(!s||!e?.isBuilding()||e.name!==a||e.owner!==this.gameObject.owner)):this.warheadRules.electricAssault?this.targetChecks.push((e,t,i,r,s)=>!(!r&&!s||!e?.isBuilding()||!e.overpoweredTrait||e.owner!==this.gameObject.owner)):this.weaponRules.damage<0?this.targetChecks.push((e,t,i)=>!!(e!==this.gameObject&&e?.isUnit()&&i.areFriendly(e,this.gameObject)&&e.healthTrait.health<100&&this.gameObject.isAircraft()===e.isAircraft())):(this.gameObject.rules.attackCursorOnFriendlies||this.warheadRules.bombDisarm?this.targetChecks.push((e,t,i,r,s)=>!s&&!!(!this.warheadRules.bombDisarm||e?.isTechno()&&e.tntChargeTrait?.hasCharge())):this.targetChecks.push((e,t,i,r)=>!((!r||this.warheadRules.mindControl)&&e?.isTechno()&&i.areFriendly(e,this.gameObject))),this.targetChecks.push((e,t,i)=>!(e?.isTechno()&&e.cloakableTrait?.isCloaked()&&!i.alliances.haveSharedIntel(this.gameObject.owner,e.owner))),this.weaponRules.limboLaunch&&this.targetChecks.push((e,t,i,r,s)=>!(s&&e&&(e.isVehicle()||e.isAircraft())&&e.parasiteableTrait?.isInfested())),this.warheadRules.ivanBomb&&this.targetChecks.push(e=>!(!e?.isTechno()||!e.tntChargeTrait||e.tntChargeTrait.hasCharge())),this.warheadRules.parasite&&this.targetChecks.push((e,t,i,r)=>!!(!e&&r||e?.isInfantry()||(e?.isVehicle()||e?.isAircraft())&&e.parasiteableTrait)),this.warheadRules.mindControl&&this.targetChecks.push(e=>!(!e?.isTechno()||!e.mindControllableTrait)),this.warheadRules.temporal||this.targetChecks.push((e,t,i,r,s)=>!(s&&e?.isTechno()&&e.warpedOutTrait.isInvulnerable())),this.gameObject.rules.natural&&this.targetChecks.push(e=>!e?.isTechno()||!e.rules.unnatural)),this.targetChecks.push((e,t)=>this.canTargetZone(e,t))}canTarget(t,i,r,s,a){return this.targetChecks.every(e=>e(t,i,r,s,a))}canTargetZone(e,t){let i;if(e?.isUnit()){if(e?.isInfantry()&&e.stance===StanceType.Paradrop&&2<e.tileElevation)return this.projectileRules.isAntiAir&&(this.projectileRules.isAntiGround||this.weaponType===WeaponType.Secondary);if(e.zone===ZoneType.Air)return this.projectileRules.isAntiAir;if(this.weaponType===WeaponType.Secondary&&this.projectileRules.isAntiAir&&!this.projectileRules.isAntiGround)return!1;i=e.zone}else i=t.landType===LandType.Water?ZoneType.Water:ZoneType.Ground;return i===ZoneType.Water?this.canTargetNaval(this.gameObject.rules.navalTargeting,this.gameObject,e,this.weaponType):this.canTargetLand(this.gameObject.rules.landTargeting,this.weaponType)}canTargetLand(e,t){switch(e){case LandTargeting.LandOk:return!0;case LandTargeting.LandNotOk:return!1;case LandTargeting.LandSecondary:return t===WeaponType.Secondary;default:throw new Error(`Unhandled LandTargeting value "${e}"`)}}canTargetNaval(e,t,i,r){switch(e){case NavalTargeting.UnderwaterNever:return!i||!(i.isVehicle()&&i.submergibleTrait?.isSubmerged());case NavalTargeting.UnderwaterSecondary:return i&&i.isVehicle()&&i.submergibleTrait&&!t.rules.spawned?r===WeaponType.Secondary:r===WeaponType.Primary;case NavalTargeting.UnderwaterOnly:return!!(i&&i.isVehicle()&&i.submergibleTrait);case NavalTargeting.OrganicSecondary:return i?.isTechno()&&i.rules.organic?r===WeaponType.Secondary:r===WeaponType.Primary;case NavalTargeting.SealSpecial:return i?.isTechno()&&i.rules.naval&&!i.rules.organic&&(i.isBuilding()||i.rules.speedType===SpeedType.Float)?r===WeaponType.Secondary:r===WeaponType.Primary;case NavalTargeting.NavalAll:return!0;case NavalTargeting.NavalNone:return!1;default:throw new Error(`Unhandled NavalTargeting value "${e}"`)}}}const ARCING_PROJECTILE_SPEED=50,BOMBER_BURST=5,NON_FIGHTER_BURST=2,FIGHTER_BURST=1;class Weapon{static factory(e,t,i,r,s){var a=r.getWeapon(e);let n=a.warhead;n===Warhead.SPECIAL_WARHEAD_NAME&&(n=Weapon.findSpecialWarheadName(a,i,r));var o=new Warhead(r.getWarhead(n)),e=r.getProjectile(a.projectile),r=new WeaponTargeting(t,e,a,o.rules,i,r.general);return new this(t,i,a,o,e,s||new FlhCoords,r)}static findSpecialWarheadName(e,t,i){let r;if(!e.spawner)throw new Error(`Weapon "${e.name} can't use "Special" warhead without Spawner=yes`);if(t.rules.spawns===i.general.v3Rocket.type)r=i.combatDamage.v3Warhead;else if(t.rules.spawns===i.general.dMisl.type)r=i.combatDamage.dMislWarhead;else{if(!t.rules.spawns)throw new Error(`Can't use "Special" warhead on unit type "${t.name}" without "Spawns"`);t=i.getObject(t.rules.spawns,ObjectType.Aircraft);if(!t.primary)throw new Error(`Spawned unit "${t.name}" doesn't have a primary weapon`);r=i.getWeapon(t.primary).warhead}return r}static computeSpeed(e,t){return t.arcing?.75*ObjectRules.iniSpeedToLeptonsPerTick(ARCING_PROJECTILE_SPEED,100):!t.rot||t.inviso||e.isLaser||e.isElectricBolt?Number.POSITIVE_INFINITY:e.speed}constructor(e,t,i,r,s,a,n){this.type=e,this.gameObject=t,this.rules=i,this.warhead=r,this.projectileRules=s,this.flh=a,this.targeting=n,this.cooldownTicks=0,this.burstsLeft=0,this.burstIndex=0,this.useBurstDelay=!1,this.lateralMuzzleMult=1,this.distributedFireAngle=t.rules.distributedFire&&t.rules.radialFireSegments?-90:0}get name(){return this.rules.name}get minRange(){return this.rules.minimumRange}get range(){return this.gameObject.isBuilding()&&!this.gameObject.overpoweredTrait&&this.type===WeaponType.Secondary&&this.gameObject.primaryWeapon?Math.min(this.gameObject.primaryWeapon.rules.range,this.rules.range):this.rules.range}get speed(){return Weapon.computeSpeed(this.rules,this.projectileRules)}get rof(){let e=this.rules.rof;return this.gameObject.isBuilding()&&this.gameObject.garrisonTrait?.isOccupied()&&(e/=this.gameObject.garrisonTrait.units.length),this.gameObject.veteranTrait&&(e*=this.gameObject.veteranTrait.getVeteranRofMultiplier()),Math.floor(e)}getCooldownTicks(){return this.cooldownTicks}expireCooldown(){this.cooldownTicks=0}resetCooldown(){this.cooldownTicks=this.rof}hasBurstsLeft(){return 0<this.burstsLeft}resetBursts(){this.burstsLeft=0,this.burstIndex=0,this.resetCooldown(),this.gameObject.ammoTrait&&0<this.gameObject.ammoTrait.ammo&&this.gameObject.ammoTrait.ammo--}tick(){0<this.cooldownTicks&&this.cooldownTicks--}getBurstsFired(){return this.burstIndex}fire(s,a,n=1){let o=this.gameObject,e,t=0;if(!o.airSpawnTrait||!this.rules.spawner||(e=o.airSpawnTrait.prepareLaunch(o,s,a),t=o.airSpawnTrait.availableSpawns,e)){this.burstsLeft?(this.burstsLeft--,this.burstIndex++,this.lateralMuzzleMult*=-1):(this.useBurstDelay=!1,this.burstIndex=0,e?this.burstsLeft=t:this.gameObject.isAircraft()?this.burstsLeft=this.projectileRules.iniRot<=1?BOMBER_BURST-1:this.gameObject.rules.fighter?FIGHTER_BURST-1:NON_FIGHTER_BURST-1:(this.burstsLeft=this.rules.burst-1,this.useBurstDelay=!0),this.lateralMuzzleMult=1),0<this.burstsLeft&&(e&&0<t?this.cooldownTicks=this.rules.iniSpeed:this.gameObject.isAircraft()?this.cooldownTicks=this.rules.rof:this.cooldownTicks=this.useBurstDelay&&void 0!==this.gameObject.rules.burstDelay[this.burstIndex]?this.gameObject.rules.burstDelay[this.burstIndex]:a.generateRandomInt(3,5)),this.burstsLeft||this.resetBursts(),this.rules.limboLaunch&&(a.limboObject(this.gameObject,{selected:a.getUnitSelection().isSelected(this.gameObject),controlGroup:a.getUnitSelection().getOrCreateSelectionModel(this.gameObject).getControlGroupNumber()}),this.warhead.rules.parasite&&(s.obj?.isVehicle()||s.obj?.isAircraft())&&s.obj.parasiteableTrait&&(s.obj.parasiteableTrait.beingBoarded=!0));let i=e??a.createProjectile(this.projectileRules.name,this.gameObject,this,s,!1);i.isAircraft()||(i.baseDamageMultiplier=n*(this.gameObject.isUnit()?this.gameObject.crateBonuses.firepower:1));let r=this.flh.clone();r.lateral*=this.lateralMuzzleMult;var l=o.position.getMapPosition();if(a.map.isWithinHardBounds(l)){i.position.moveToLeptons(l),i.position.tileElevation=o.position.tileElevation;let e=new Vector2(r.lateral,r.forward);n=this.getMuzzleFacing()+this.distributedFireAngle;e=rotateVec2(e,n);var l=rotateVec2(l=new Vector2(0,o.art.turretOffset),o.direction);e.add(l),o.rules.radialFireSegments&&o.rules.distributedFire&&(l=Math.floor(180/o.rules.radialFireSegments),this.distributedFireAngle=(this.distributedFireAngle+l+90)%180-90),i.direction=n,o.isBuilding()&&o.rules.turretAnim&&(h=Coords.screenDistanceToWorld(o.rules.turretAnimX,o.rules.turretAnimY),n=o.getFoundationCenterOffset(),i.position.moveByLeptons(-n.x+h.x,-n.y+h.y));let t=new Vector3_Vector3(e.x,r.vertical,-e.y);var h=t.clone().add(i.position.worldPosition);if(a.map.isWithinHardBounds(h)&&i.position.moveByLeptons3(t),i.tileElevation<0&&(i.position.tileElevation=0),i.isAircraft()?a.unlimboObject(i,i.position.tile):a.spawnObject(i,i.position.tile),this.rules.revealOnFire&&s.obj?.isTechno()){let e=a.mapShroudTrait.getPlayerShroud(s.obj.owner);e?.isShrouded(o.tile,o.tileElevation)&&e.revealTemporarily(o)}this.rules.decloakToFire&&this.gameObject.cloakableTrait?.uncloak(a),a.events.dispatch(new WeaponFireEvent(this,this.gameObject))}else e&&(e.owner.removeOwnedObject(e),e.dispose())}}getMuzzleFacing(){let e=this.gameObject,t;return t=!e.isInfantry()&&!e.isAircraft()&&(e.isBuilding()||e.isVehicle())&&e.turretTrait?e.turretTrait.facing:e.direction,t}}Weapon.NUKE_PAYLOAD_NAME="NukePayload";class NukeEffect extends SuperWeaponEffect{constructor(e,t,i,r){super(e,t,i),this.weaponType=r}onStart(t){var i=t.rules.getWeapon(this.weaponType),r=t.createTarget(void 0,this.tile),s=this.owner.getOwnedObjectsByType(ObjectType.Building).find(e=>e.rules.nukeSilo);if(s){let e=Weapon.factory(i.name,WeaponType.Primary,s,t.rules);e.fire(r,t)}else this.fireLooseNuke(i,r,t)}fireLooseNuke(t,i,r){var s=new Vector2(this.tile.rx+.5,this.tile.ry+.5).multiplyScalar(Coords.LEPTONS_PER_TILE);if(r.map.isWithinHardBounds(s)){let e=r.createLooseProjectile(t.name,this.owner,i);e.position.moveToLeptons(s),e.position.tileElevation=Coords.worldToTileHeight(e.rules.detonationAltitude),r.spawnObject(e,e.position.tile)}}onTick(e){return!0}}class LightningStormCloudEvent{constructor(e){this.position=e,this.type=EventType.LightningStormCloud}}class LightningStormManifestEvent{constructor(e){this.target=e,this.type=EventType.LightningStormManifest}}!function(e){e[e.Approaching=0]="Approaching",e[e.Manifesting=1]="Manifesting"}(State=State||{});class LightningStormEffect extends SuperWeaponEffect{constructor(){super(...arguments),this.state=State.Approaching,this.clouds=[]}onStart(e){e=e.rules.general.lightningStorm;this.manifestStartTimer=e.deferment,this.manifestEndTimer=e.duration,this.nextDirectHitTimer=0,this.nextRandomHitTimer=0}onTick(t){if(this.state===State.Approaching&&(0<this.manifestStartTimer?this.manifestStartTimer--:(this.state=State.Manifesting,t.events.dispatch(new LightningStormManifestEvent(this.tile)))),this.state===State.Manifesting){var i,s=t.rules.general.lightningStorm;if(0<this.manifestEndTimer&&(this.manifestEndTimer--,0<this.nextDirectHitTimer&&this.nextDirectHitTimer--,this.nextDirectHitTimer<=0&&(this.nextDirectHitTimer=s.hitDelay,this.spawnCloudAt(this.tile,t)),0<this.nextRandomHitTimer&&this.nextRandomHitTimer--,this.nextRandomHitTimer<=0)){this.nextRandomHitTimer=s.scatterDelay;var a=Math.floor(s.cellSpread/2);let i=s.separation,r=new RangeHelper(t.map.tileOccupation),e=new RandomTileFinder(t.map.tiles,t.map.mapBounds,this.tile,a,t,t=>!this.clouds.some(e=>r.tileDistance(t,e.tile)<i),!1);a=e.getNextTile();a&&this.spawnCloudAt(a,t)}for(i of this.clouds.slice())if(0<i.ticksLeft){if(i.ticksLeft--,i.ticksLeft===Math.floor(i.durationTicks/2)){var r=s.warhead;let e=new Warhead(t.rules.getWarhead(r));var n=i.tile,o=t.map.tileOccupation.getBridgeOnTile(n),l=o?.tileElevation??0,r=t.map.getTileZone(n);e.detonate(t,s.damage,n,l,Coords.tile3dToWorld(n.rx+.5,n.ry+.5,n.z+l),r,o?CollisionType.OnBridge:CollisionType.None,t.createTarget(o,n),{player:this.owner,weapon:void 0},SpecialWarheadType.LightningStrike)}}else this.clouds.splice(this.clouds.indexOf(i),1);if(!this.clouds.length&&this.manifestEndTimer<=0)return!0}return!1}spawnCloudAt(e,t){var i=t.rules.audioVisual.weatherConClouds,i=t.generateRandomInt(0,i.length-1);let r=t.art.getAnimation(t.rules.audioVisual.weatherConClouds[i]);i=r.art.getNumber("Rate",60*GameSpeed.BASE_TICKS_PER_SECOND)/60,i=Math.floor(GameSpeed.BASE_TICKS_PER_SECOND/i*60);this.clouds.push({tile:e,durationTicks:i,ticksLeft:i});i=(t.map.tileOccupation.getBridgeOnTile(e)?.tileElevation??0)+Coords.worldToTileHeight(t.rules.general.flightLevel),i=Coords.tile3dToWorld(e.rx+.5,e.ry+.5,e.z+i);t.events.dispatch(new LightningStormCloudEvent(i))}}class IronCurtainEffect extends SuperWeaponEffect{onStart(e){var t,i,r=e.rules.combatDamage.ironCurtainDuration,s={player:this.owner};let a=new RadialTileFinder(e.map.tiles,e.map.mapBounds,this.tile,{width:1,height:1},0,1,()=>!0);for(;t=a.getNextTile();)for(i of e.map.getGroundObjectsOnTile(t))!i.isTechno()||i.isDestroyed||i.isUnit()&&i.tile!==t||i.rules.missileSpawn||(i.rules.organic?e.destroyObject(i,s):(i.invulnerableTrait.setActiveFor(r,e.currentTick),(i.isVehicle()||i.isAircraft())&&i.parasiteableTrait?.isInfested()&&i.parasiteableTrait.destroyParasite(s,e)))}onTick(e){return!0}}class ChronoSphereEffect extends SuperWeaponEffect{constructor(e,t,i,r){super(e,t,i),this.tile2=r,this.objectsToTeleport=[]}onStart(i){this.delayTicks=i.rules.general.chronoDelay;let r=i.map.tiles;for(let t=-1;t<=1;t++)for(let e=-1;e<=1;e++){var s=r.getByMapCoords(this.tile.rx+t,this.tile.ry+e);if(s){var a,n=!!s.onBridgeLandType,o=r.getByMapCoords(this.tile2.rx+t,this.tile2.ry+e);for(a of i.map.getGroundObjectsOnTile(s))!a.isUnit()||a.tile!==s||a.onBridge!==n||a.isInfantry()&&a.stance===StanceType.Paradrop&&2<a.tileElevation||a.isDisposed||a.invulnerableTrait.isActive()||(a.rules.organic&&!a.rules.teleporter||!o?i.destroyObject(a,{player:this.owner}):a.warpedOutTrait.isActive()||(a.warpedOutTrait.setActive(!0,!0,i),this.objectsToTeleport.push({obj:a,destTile:o})))}}}onTick(c){if(0<this.delayTicks&&this.delayTicks--,this.delayTicks)return!1;for(let{obj:l,destTile:h}of this.objectsToTeleport)if(l.isSpawned){let i=!1,r=h?c.map.tileOccupation.getBridgeOnTile(h):void 0,s=c.map.getGroundObjectsOnTile(h),a=s.find(e=>e.isBuilding());var d=s.some(e=>c.rules.general.padAircraft.includes(e.name)),t=c.rules.general.padAircraft.includes(l.name)&&!!a?.helipadTrait&&!!a.dockTrait?.getAllDockTiles().includes(h)&&!a.dockTrait.hasReservedDockAt(a.dockTrait.getDockNumberByTile(h))&&a.owner===l.owner;let e=!1,n=l.rules.speedType,o=l.isInfantry();l.rules.movementZone===MovementZone.Fly&&(n=SpeedType.Wheel);var u=c.map.mapBounds.isWithinBounds(h);if(!(t||c.map.terrain.getPassableSpeed(h,n,o,!!r)&&u)){let t=!1;if(!d&&(0<c.map.terrain.getPassableSpeed(h,n,o,!!r,void 0,!0)||!u)){a&&(i=!0);let e=new RadialTileFinder(c.map.tiles,c.map.mapBounds,h,{width:1,height:1},1,15,e=>0<c.map.terrain.getPassableSpeed(e,n,o,!!e.onBridgeLandType)&&!c.map.terrain.findObstacles({tile:e,onBridge:!!e.onBridgeLandType},l).length);u=e.getNextTile();u&&(h=u,r=c.map.tileOccupation.getBridgeOnTile(h),s=c.map.getGroundObjectsOnTile(h),t=!0)}t||(l.moveTrait.teleportUnitToTile(h,r,!0,!1,c),l.warpedOutTrait.setActive(!1,!0,c),c.map.getTileZone(h)===ZoneType.Water&&(l.deathType=DeathType.Sink),c.destroyObject(l,{player:this.owner}),e=!0)}for(let t of s)t.isDisposed||t.isUnit()&&(this.objectsToTeleport.some(({obj:e})=>e===t)||t.onBridge!==!!r&&t.tile===h||2<Math.abs(t.tileElevation-l.tileElevation)||(t.isInfantry()&&t.stance!==StanceType.Paradrop&&(t.deathType=DeathType.Crush),c.destroyObject(t,{player:this.owner,obj:l})));if(!e){if(l.moveTrait.teleportUnitToTile(h,r,!0,!1,c),t&&a?.dockTrait){t=a.dockTrait.getAllDockTiles().indexOf(h);if(a.dockTrait.undockUnitAt(t),a.dockTrait.hasReservedDockAt(t))throw new Error("Target building dock is already reserved by another unit");a.dockTrait.dockUnitAt(l,t)}i?l.warpedOutTrait.setTimed(c.rules.general.chronoDelay,!1,c):l.warpedOutTrait.setActive(!1,!0,c)}}return!0}}(NotifySuperWeaponDeactivate=NotifySuperWeaponDeactivate||{}).onDeactivate=Symbol();class SuperWeaponsTrait{constructor(){this.effects=[]}[NotifyTick.onTick](i){for(var e of i.getCombatants()){var t;for(t of e.superWeaponsTrait.getAll())t.update(i)}for(let t of this.effects)t.status===EffectStatus.NotStarted&&(t.onStart(i),t.status=EffectStatus.Running),t.onTick(i)&&(t.status=EffectStatus.Finished,i.traits.filter(NotifySuperWeaponDeactivate).forEach(e=>{e[NotifySuperWeaponDeactivate.onDeactivate](t.type,t.owner,i)}));this.effects=this.effects.filter(e=>e.status!==EffectStatus.Finished)}[NotifyPower.onPowerLow](e,t){e.superWeaponsTrait?.getAll()?.filter(e=>e.rules.isPowered).forEach(e=>{this.updateTimer(e,!1)})}[NotifyPower.onPowerRestore](e,t){e.superWeaponsTrait?.getAll()?.filter(e=>e.rules.isPowered).forEach(e=>{this.updateTimer(e,!0)})}[NotifyPower.onPowerChange](e,t){}[NotifyWarpChange.onChange](e,t){var i;e.owner.powerTrait&&e.isBuilding()&&e.superWeaponTrait&&((i=e.superWeaponTrait.getSuperWeapon(e))&&this.updateTimer(i,!e.owner.powerTrait.isLowPower()))}updateTimer(e,t){var i=this.superWeaponHasValidBuilding(e);t&&i?e.resumeTimer():e.pauseTimer()}superWeaponHasValidBuilding(t){return[...t.owner.buildings].find(e=>!(e.superWeaponTrait?.getSuperWeapon(e)!==t||e.warpedOutTrait.isActive()&&t.rules.isPowered))}addEffect(e){this.effects.push(e)}activateSuperWeapon(t,e,i,r,s){let a=e.superWeaponsTrait?.getAll().find(e=>e.rules.type===t);if(a&&a.status===SuperWeaponStatus.Ready){if(a.oneTimeOnly){e.superWeaponsTrait.remove(a.name);for(var n of e.buildings)n.rules.superWeapon===a.name&&n.superWeaponTrait&&n.superWeaponTrait.addSuperWeaponToPlayerIfNeeded(e,i)}else a.resetTimer();this.activateEffect(a.rules,e,i,r,s)}}activateEffect(e,i,r,s,a,n=!1){const o=e.type;if(void 0!==o){let t=[];switch(o){case SuperWeaponType.AmerParaDrop:for(var[l,h]of r.rules.general.paradrop.amerParaDrop.entries())r.rules.hasObject(h.inf,ObjectType.Infantry)?t.push(new ParadropEffect(o,i,s,h,l)):console.warn(`Can't paradrop unknown infantry type "${h.inf}"`);break;case SuperWeaponType.ParaDrop:{let e=r.rules.general.paradrop.getParadropSquads(i.country.side);for(var[c,d]of e.entries())r.rules.hasObject(d.inf,ObjectType.Infantry)?t.push(new ParadropEffect(o,i,s,d,c)):console.warn(`Can't paradrop unknown infantry type "${d.inf}"`);break}case SuperWeaponType.MultiMissile:if(!e.weaponType)throw new Error("Missing WeaponType in super weapon rules");t.push(new NukeEffect(o,i,s,e.weaponType));break;case SuperWeaponType.LightningStorm:t.push(new LightningStormEffect(o,i,s));break;case SuperWeaponType.IronCurtain:t.push(new IronCurtainEffect(o,i,s));break;case SuperWeaponType.ChronoSphere:if(!a)throw new Error("Missing tile2 action param");t.push(new ChronoSphereEffect(o,i,s,a))}for(var u of t)this.addEffect(u);r.traits.filter(NotifySuperWeaponActivate).forEach(e=>{e[NotifySuperWeaponActivate.onActivate](o,i,r,s,a)}),r.events.dispatch(new SuperWeaponActivateEvent(o,i,s,a,n))}}}class ObjectCloakChangeEvent{constructor(e){this.target=e,this.type=EventType.ObjectCloakChange}}(NotifyDamage=NotifyDamage||{}).onDamage=Symbol();class CloakableTrait{constructor(e,t){this.gameObject=e,this.cloakDelayMinutes=t,this.isActive=!1,this.resetCloakCooldown()}isCloaked(){return this.isActive}uncloak(e){var t=this.isActive;this.resetCloakCooldown(),t&&(this.isActive=!1,e.events.dispatch(new ObjectCloakChangeEvent(this.gameObject)))}resetCloakCooldown(){this.cooldownTicks=Math.floor(60*this.cloakDelayMinutes*GameSpeed.BASE_TICKS_PER_SECOND)}[NotifySpawn.onSpawn](e,t){this.resetCloakCooldown()}[NotifyTick_NotifyTick.onTick](e,t){0<this.cooldownTicks&&this.cooldownTicks--,!(this.cooldownTicks<=0)||this.isActive||e.isVehicle()&&e.submergibleTrait&&!e.submergibleTrait.isSubmerged()||e.temporalTrait.getTarget()||(this.isActive=!0,t.events.dispatch(new ObjectCloakChangeEvent(this.gameObject)))}[NotifyDamage.onDamage](e,t){this.uncloak(t)}dispose(){this.gameObject=void 0}}!function(e){e[e.Riparius=0]="Riparius",e[e.Cruentus=1]="Cruentus",e[e.Vinifera=2]="Vinifera",e[e.Aboreus=3]="Aboreus",e[e.Ore=0]="Ore",e[e.Gems=1]="Gems",e[e.Ore2=2]="Ore2",e[e.Ore3=3]="Ore3"}(TiberiumType=TiberiumType||{});class OreOverlayTypes{static getOverlayTibType(e){return this.isRiparius(e)?TiberiumType.Riparius:this.isCruentus(e)?TiberiumType.Cruentus:this.isVinifera(e)?TiberiumType.Vinifera:this.isAboreus(e)?TiberiumType.Aboreus:void 0}static isRiparius(e){return e>=this.minIdRiparius&&e<=this.maxIdRiparius}static isCruentus(e){return e>=this.minIdCruentus&&e<=this.maxIdCruentus}static isVinifera(e){return e>=this.minIdVinifera&&e<=this.maxIdVinifera}static isAboreus(e){return e>=this.minIdAboreus&&e<=this.maxIdAboreus}}OreOverlayTypes.minIdRiparius=102,OreOverlayTypes.maxIdRiparius=127,OreOverlayTypes.minIdCruentus=27,OreOverlayTypes.maxIdCruentus=38,OreOverlayTypes.minIdVinifera=127,OreOverlayTypes.maxIdVinifera=146,OreOverlayTypes.minIdAboreus=147,OreOverlayTypes.maxIdAboreus=166;class OreSpread{static calculateOverlayId(e,t){var i=t.dx,t=t.dy,i=Math.floor((t-9)/2%12*((t-8)/2%12)%12-(i-13)/2%12*((i-12)/2%12)%12+12e4);return i%=12,e===TiberiumType.Riparius?OreOverlayTypes.minIdRiparius+i:e===TiberiumType.Cruentus?OreOverlayTypes.minIdCruentus+i:e===TiberiumType.Vinifera?OreOverlayTypes.minIdVinifera+i:e===TiberiumType.Aboreus?OreOverlayTypes.minIdAboreus+i:void 0}}var SequenceType,LightingType,PowerLevel,QueueType,QueueStatus,AttackState,NotifySell,LayerType,NotifyWarpChange_NotifyWarpChange,NotifyProduceUnit,FactoryStatus,NotifyBuildStatus,RepairStatus,ShroudType,ShroudFlag,BuildStatus,NotifyOrder,OrderType,HarvesterStatus,NotifyHeal,ProjectileState,DeployFireState,NotifyHealthChange,NotifyHealthChange_NotifyHealthChange,HealthLevel,SpawnStatus,NotifyTargetDestroy,BridgeHeadType,Box2_THREE=__webpack_require__(70);class Box2 extends Box2_THREE.Box2{}const EDGE_SPAWN_CHANCE=2/3,WATER_MAP_EDGE_SPAWN_CHANCE=1/3,UNSUPPORTED_POWERUP_TYPES=[PowerupType.IonStorm,PowerupType.Gas,PowerupType.Pod,PowerupType.Squad];class CrateGeneratorTrait{constructor(e){this.randomCrateSpawn=e,this.crates=[],this.availEdgeTiles=[],this.allTiles=[]}init(n){var o=n.map.tiles.getMapSize();let l=n.map.tiles,e=[],h=0;for(let a=0;a<o.width;++a){let t,i,r=!1,s=!1;for(let e=0;e<o.height;++e){var c=l.getByMapCoords(a,e);if(c&&this.canPlaceCrateOnTile(n,c)){var d=n.map.getTileZone(c)===ZoneType.Water;t?(d||(i=c),s=d):d?r=s=!0:t=i=c}else if(t&&!c)break}t&&(e.push(t),i&&i!==t&&e.push(i),r||s||h++)}this.availEdgeTiles=e,this.allTiles=l.getAll(),this.mapEdgeIsWater=0===h,this.minCrates=n.rules.crateRules.crateMinimum*n.gameOpts.humanPlayers.filter(e=>e.countryId!==OBS_COUNTRY_ID).length}[NotifyTick.onTick](t){for(var e of this.crates)e.ticksLeft--,e.ticksLeft<=0&&(t.unspawnObject(e.obj),e.obj.dispose());if(this.crates=this.crates.filter(e=>0<e.ticksLeft),this.randomCrateSpawn)for(let e=0;e<this.minCrates-this.crates.length&&this.spawnCrateAtRandom(this.allTiles,t);e++);}spawnCrateAtRandom(e,t){e=this.chooseSpawnTile(e,t);if(e)return this.spawnRandomCrateAt(e,t)}spawnRandomCrateAt(e,t){if(this.canPlaceCrateOnTile(t,e)){var i=t.map.getTileZone(e,!0)===ZoneType.Water,i=this.choosePowerup(i,t.rules.powerups.powerups,t);if(i)return this.spawnCrateAt(e,i,t)}}spawnCrateAt(t,i,r){if(this.canPlaceCrateOnTile(r,t)){var s=r.map.getTileZone(t,!0)===ZoneType.Water,a=r.rules.crateRules,s=s?a.waterCrateImg:a.crateImg;let e=r.createObject(ObjectType.Overlay,s);e.overlayId=r.rules.getOverlayId(s),e.value=0,r.spawnObject(e,t);r=60*a.crateRegen*GameSpeed.BASE_TICKS_PER_SECOND*(.5+1.5*r.generateRandom());return this.crates.push({obj:e,powerup:i,ticksLeft:r}),e}}chooseSpawnTile(e,t){return t.generateRandom()<(this.mapEdgeIsWater?WATER_MAP_EDGE_SPAWN_CHANCE:EDGE_SPAWN_CHANCE)&&this.availEdgeTiles.length&&(e=this.availEdgeTiles),this.chooseRandomTile(e,t)}chooseRandomTile(e,t){let i;let r=0;for(;i=e[t.generateRandomInt(0,e.length-1)],r++,r<100&&!this.canPlaceCrateOnTile(t,i););if(100<=r){var s=t.map.tileOccupation.getEmptyTiles();if(!s.length)return;i=s[t.generateRandomInt(0,s.length-1)]}return i}canPlaceCrateOnTile(e,t){return e.map.mapBounds.isWithinBounds(t)&&!e.map.getGroundObjectsOnTile(t).length&&0<e.map.terrain.getPassableSpeed(t,SpeedType.Amphibious,!1,!1)&&t.terrainType!==TerrainType.Shore&&0===t.rampType}choosePowerup(t,i,r){if((i=t?i.filter(e=>e.waterAllowed):i).length){var s,t=i.reduce((e,t)=>e+t.probShares,0),a=r.generateRandomInt(0,t);let e=0;for(s of i)if(e+=s.probShares,a<e)return s}}peekInsideCrate(t){return this.crates.find(e=>e.obj===t)?.powerup.type}pickupCrate(e,t,i){let r=this.crates.find(e=>e.obj===t);if(r){this.crates.splice(this.crates.indexOf(r),1),i.unspawnObject(r.obj),r.obj.dispose();let t=this.grantPowerup(e,r.powerup,r.obj.tile,i);var s;return void 0!==t&&(e.owner.cratesPickedUp++,s=i.rules.powerups.powerups.find(e=>e.type===t),i.events.dispatch(new CratePickupEvent(s,e.owner,e,r.obj.tile))),this.randomCrateSpawn&&this.spawnCrateAtRandom(this.allTiles,i),t}}grantPowerup(t,i,r,s){let a=t.owner,n=!1;if(a.isCombatant()){if(i.type===PowerupType.Unit){let e;if(![...a.buildings].some(e=>e.rules.constructionYard)&&s.rules.crateRules.freeMCV){let t=s.rules.general.baseUnit;if(!a.getOwnedObjects(!0).some(e=>t.includes(e.name))&&a.credits>=[...s.rules.ai.buildPower,...s.rules.ai.buildRefinery].map(e=>s.rules.getBuilding(e)).filter(e=>e.aiBasePlanningSide===a.country.side).reduce((e,t)=>e+t.cost,0)){var o=t.find(e=>{let t=s.rules.getObject(e,ObjectType.Vehicle);return t.isAvailableTo(a.country)&&t.hasOwner(a.country)});if(!o)throw new Error("No suitable MCV found for player country "+a.country?.name);e=s.rules.getObject(o,ObjectType.Vehicle)}}if(e||(o=(o=s.rules.crateRules.unitCrateType)?s.rules.hasObject(o,ObjectType.Vehicle)?[s.rules.getObject(o,ObjectType.Vehicle)]:[]:[...s.rules.vehicleRules.values()].filter(e=>e.crateGoodie&&0<s.map.terrain.getPassableSpeed(r,e.speedType,!1,!1))).length&&(e=o[s.generateRandomInt(0,o.length-1)]),e){let t=s.createUnitForPlayer(e,a);var l=new RadialTileFinder(s.map.tiles,s.map.mapBounds,r,{width:1,height:1},0,3,e=>0<s.map.terrain.getPassableSpeed(e,t.rules.speedType,t.isInfantry(),!1)&&!s.map.terrain.findObstacles({tile:e,onBridge:void 0},t).length).getNextTile();l?(s.spawnObject(t,l),n=!0):(a.removeOwnedObject(t),t.dispose())}}else if(i.type===PowerupType.Money){if(!i.data)throw new Error("Money powerup missing data field");l=Math.floor(Number(i.data)*(.55+2*s.generateRandom()*.45));a.credits=Math.max(0,a.credits+l),0<l&&(a.creditsGained+=l),n=!0}else if(i.type===PowerupType.HealBase){var e;for(e of a.getOwnedObjects(!0))e.isDestroyed||e.healthTrait.healToFull(void 0,s);n=!0}else if(i.type===PowerupType.Reveal)s.mapShroudTrait.revealMap(a,s),n=!0;else if(i.type===PowerupType.Darkness)s.mapShroudTrait.resetShroud(a,s),n=!0;else if(i.type===PowerupType.Veteran){if(t.veteranTrait&&!t.veteranTrait.isMaxLevel()){n=!0;var h,c=Number(i.data);for(h of this.getUnitsInCrateRadius(s,r,a))h.veteranTrait?.promote(c,s)}}else if(i.type===PowerupType.Armor){if(1===t.crateBonuses.armor){n=!0;var d,u=Number(i.data);for(d of this.getUnitsInCrateRadius(s,r,a))1===d.crateBonuses.armor&&(d.crateBonuses.armor=u)}}else if(i.type===PowerupType.Firepower){if(1===t.crateBonuses.firepower){n=!0;var p,g=Number(i.data);for(p of this.getUnitsInCrateRadius(s,r,a))1===p.crateBonuses.firepower&&(p.crateBonuses.firepower=g)}}else if(i.type===PowerupType.Speed){if(1===t.crateBonuses.speed){n=!0;var m,y=Number(i.data);for(m of this.getUnitsInCrateRadius(s,r,a))1===m.crateBonuses.speed&&(m.crateBonuses.speed=y)}}else if(i.type===PowerupType.Cloak){if(!t.cloakableTrait){n=!0;for(var T of this.getUnitsInCrateRadius(s,r,a))T.cloakableTrait||(T.cloakableTrait=new CloakableTrait(T,s.rules.general.cloakDelay),s.addObjectTrait(T,T.cloakableTrait))}}else if(i.type===PowerupType.ICBM){var f=[...s.rules.superWeaponRules.values()].find(e=>e.type===SuperWeaponType.MultiMissile);if(f&&a.superWeaponsTrait&&!a.superWeaponsTrait.has(f.name)){let e=s.createSuperWeapon(f.name,a,!0);e.isGift=!0,a.superWeaponsTrait.add(e),n=!0}}else if(i.type===PowerupType.Invulnerability){var v=[...s.rules.superWeaponRules.values()].find(e=>e.type===SuperWeaponType.IronCurtain);v&&(s.traits.get(SuperWeaponsTrait).activateEffect(v,a,s,r,void 0,!0),n=!0)}else if(i.type===PowerupType.Explosion||i.type===PowerupType.Napalm){n=!0;f=Number(i.data),v=i.type===PowerupType.Napalm?s.rules.combatDamage.flameDamage:s.rules.combatDamage.c4Warhead;let e=new Warhead(s.rules.getWarhead(v));e.detonate(s,f,t.tile,t.tileElevation,t.position.worldPosition,t.zone,CollisionType.None,s.createTarget(t,t.tile),{player:t.owner,weapon:void 0},SpecialWarheadType.None,void 0,0)}else{if(i.type!==PowerupType.Tiberium)return void console.warn(`Unhandled powerup type "${PowerupType[i.type]}"`);{let e=new RandomTileFinder(s.map.tiles,s.map.mapBounds,r,2,s,e=>TiberiumTrait.canBePlacedOn(e,s.map)),t,i=0;for(;i++<6&&(t=e.getNextTile());){var b=OreSpread.calculateOverlayId(TiberiumType.Ore,t);if(void 0===b)throw new Error("Expected an overlayId");let e=s.createObject(ObjectType.Overlay,s.rules.getOverlayName(b));e.overlayId=b,e.value=3,s.spawnObject(e,t),n=!0}}}if(n)return i.type;i=s.rules.powerups.powerups.find(e=>e.type===PowerupType.Money&&0<e.probShares);return i?this.grantPowerup(t,i,r,s):void 0}}getUnitsInCrateRadius(e,t,i){let r=e.rules.crateRules.crateRadius,s=new RangeHelper(e.map.tileOccupation);return e.map.technosByTile.queryRange((new Box2).setFromCenterAndSize(new Vector2(t.rx,t.ry),new Vector2(r,r))).filter(e=>e.owner===i&&e.isUnit()&&s.tileDistance(e,t)<=r)}}class PowerupsRules{constructor(){this.powerups=[]}readIni(e){for(var[s,a]of e.entries){let[e,t,i,r]=a.split(",");var n=Number(e),a=PowerupType[s];void 0!==a?UNSUPPORTED_POWERUP_TYPES.includes(a)||this.powerups.push({type:a,probShares:n,animName:"<none>"!==t.toLowerCase()?t:void 0,waterAllowed:"yes"===i,data:r}):console.warn(`Unknown powerup "${s}". Skipping.`)}return this}}const mpAllowedColors=["Gold","DarkRed","DarkBlue","DarkGreen","Orange","DarkSky","Purple","Magenta"];class Rules{constructor(e,t){this.ini=e,this.logger=t,this.buildingTypes=new Map,this.vehicleTypes=new Map,this.infantryTypes=new Map,this.aircraftTypes=new Map,this.terrainTypes=new Map,this.overlayTypes=new Map,this.overlayIdsByType=new Map,this.animationTypes=new Map,this.animationNames=new Set,this.voxelAnimTypes=new Map,this.smudgeTypes=new Map,this.warheadTypes=new Map,this.tiberiumTypes=new Map,this.superWeaponTypes=new Map,this.countryTypes=new Map,this.weaponTypes=new Map,this.allObjectRules=new Map,this.buildingRules=new Map,this.infantryRules=new Map,this.vehicleRules=new Map,this.aircraftRules=new Map,this.terrainRules=new Map,this.overlayRules=new Map,this.smudgeRules=new Map,this.voxelAnimRules=new Map,this.countryRules=new Map,this.warheadRules=new Map,this.powerups=new PowerupsRules,this.colors=new Map,this.general=new GeneralRules,this.ai=new AiRules,this.crateRules=new CrateRules,this.elevationModel=new ElevationModelRules,this.mpDialogSettings=new MpDialogSettings,this.audioVisual=new AudioVisualRules,this.combatDamage=new CombatDamageRules,this.radiation=new RadiationRules,this.landRules=new Map,this.tiberiumRules=new Map,this.superWeaponRules=new Map,this.cachedWeaponRules=new Map,this.cachedProjectileRules=new Map,this.init()}hasObject(e,t){return this.allObjectRules.get(t)?.has(e)}getObject(e,t){t=this.allObjectRules.get(t)?.get(e);if(!t)throw new Error(`Missing rules for object "${e}"`);return t}getTechnoByInternalId(e,t){let i;if(t===ObjectType.Building)i=this.buildingTypes.get(e);else if(t===ObjectType.Infantry)i=this.infantryTypes.get(e);else if(t===ObjectType.Vehicle)i=this.vehicleTypes.get(e);else{if(t!==ObjectType.Aircraft)throw new Error(`Type ${ObjectType[t]} is not a techno type`);i=this.aircraftTypes.get(e)}if(void 0===i)throw new Error(`Object type "${ObjectType[t]}" with ID "${e}" not found`);return this.getObject(i,t)}getBuilding(e){var t=this.buildingRules.get(e);if(!t)throw new Error(`Missing rules for building "${e}"`);return t}getWeapon(e){let t=this.cachedWeaponRules.get(e);if(!t){var i=this.ini.getSection(e);if(!i)throw new Error(`Weapon ${e} is missing ini section`);t=new WeaponRules(i),this.cachedWeaponRules.set(e,t)}return t}getWeaponByInternalId(e){var t=this.weaponTypes.get(e);if(!t)throw new RangeError(`Weapon with internal ID "${e}" not found`);return this.getWeapon(t)}getWarhead(t){let i=t.toLowerCase(),r=this.warheadRules.get(i);if(!r){let e=this.ini.getSection(t);if(!e&&(e=this.ini.getOrderedSections().find(e=>e.name.toLowerCase()===i),!e))throw new Error("Unknown warhead "+t);r=new WarheadRules(e),this.warheadRules.set(i,r)}return r}getProjectile(t){let i=t.toLowerCase(),r=this.cachedProjectileRules.get(i);if(!r){let e=this.ini.getSection(t);if(!e&&(e=this.ini.getOrderedSections().find(e=>e.name.toLowerCase()===i),!e))throw new Error(`Projectile ${t} is missing ini section`);r=new ProjectileRules(ObjectType.Projectile,e),this.cachedProjectileRules.set(i,r)}return r}getOverlayName(e){var t=this.overlayTypes.get(e);if(!t)throw new Error("Invalid overlay id "+e);return t}hasOverlayId(e){return this.overlayTypes.has(e)}getOverlayId(e){var t=this.overlayIdsByType.get(e);if(void 0===t)throw new Error("Invalid overlay name "+e);return t}getOverlay(e){var t=this.overlayRules.get(e);if(!t)throw new Error(`Missing rules for overlay "${e}"`);return t}getAnimationName(e){return this.animationTypes.get(e)}getCountry(e){if(!this.countryRules.has(e))throw new Error("Unknown country "+e);return this.countryRules.get(e)}getMultiplayerCountries(){return[...this.countryRules.values()].filter(e=>e.multiplay)}getMultiplayerColors(){let t=new Map;return mpAllowedColors.forEach(e=>{if(!this.colors.has(e))throw new Error(`Multiplayer color "${e}" does not exist in the rules [Colors] section.`);t.set(e,this.colors.get(e))}),t}getLandRules(e){let t=this.landRules.get(e);var i;return t||(i=e===LandType.Cliff?"Rock":LandType[e],t=(new LandRules).readIni(this.ini.getOrCreateSection(i)),this.landRules.set(e,t)),t}getTiberium(e){var t=this.tiberiumTypes.get(e);if(!t)throw new Error("Unknown tiberium type "+e);return this.tiberiumRules.get(t)}getSuperWeapon(e){if(!this.superWeaponRules.has(e))throw new Error(`Unknown superweapon type "${e}"`);return this.superWeaponRules.get(e)}getIni(){return this.ini}applySpecialFlags(e){e.initialVeteran&&(this.general.veteran.initialVeteran=!0)}init(){this.readAudioVisual(),this.readCombatDamage(),this.readRadiation(),this.readGeneral(),this.readAi(),this.readCrateRules(),this.readElevationModel(),this.readMpDialogSettings(),this.readObjectTypes("BuildingTypes",this.buildingTypes),this.readObjectTypes("InfantryTypes",this.infantryTypes),this.readObjectTypes("VehicleTypes",this.vehicleTypes),this.readObjectTypes("AircraftTypes",this.aircraftTypes),this.readObjectTypes("TerrainTypes",this.terrainTypes),this.readObjectTypes("SmudgeTypes",this.smudgeTypes),this.readObjectTypes("Animations",this.animationTypes),this.animationNames=new Set(this.animationTypes.values()),this.readObjectTypes("VoxelAnims",this.voxelAnimTypes),this.readObjectTypes("OverlayTypes",this.overlayTypes),this.overlayTypes.forEach((e,t)=>this.overlayIdsByType.set(e,t)),this.readColors(),this.readObjectTypes("Countries",this.countryTypes),this.readObjectTypes("Warheads",this.warheadTypes),this.readObjectTypes("Tiberiums",this.tiberiumTypes),this.readObjectTypes("SuperWeaponTypes",this.superWeaponTypes),this.allObjectRules.set(ObjectType.Building,this.buildingRules).set(ObjectType.Infantry,this.infantryRules).set(ObjectType.Vehicle,this.vehicleRules).set(ObjectType.Aircraft,this.aircraftRules).set(ObjectType.Terrain,this.terrainRules).set(ObjectType.Overlay,this.overlayRules).set(ObjectType.Smudge,this.smudgeRules).set(ObjectType.VoxelAnim,this.voxelAnimRules),this.readObjects(ObjectType.Building,this.buildingTypes,this.buildingRules),this.readObjects(ObjectType.Infantry,this.infantryTypes,this.infantryRules),this.readObjects(ObjectType.Vehicle,this.vehicleTypes,this.vehicleRules),this.readObjects(ObjectType.Aircraft,this.aircraftTypes,this.aircraftRules),this.readObjects(ObjectType.Terrain,this.terrainTypes,this.terrainRules),this.readObjects(ObjectType.Overlay,this.overlayTypes,this.overlayRules),this.readObjects(ObjectType.Smudge,this.smudgeTypes,this.smudgeRules),this.readObjects(ObjectType.VoxelAnim,this.voxelAnimTypes,this.voxelAnimRules),this.readCountries(),this.readWarheads(),this.readPowerups(),this.readTiberiums(),this.readSuperWeapons(),this.buildWeaponsList()}readAudioVisual(){var e=this.ini.getSection("AudioVisual");if(!e)throw new Error("Missing [AudioVisual] section");this.audioVisual.readIni(e)}readCombatDamage(){var e=this.ini.getSection("CombatDamage");if(!e)throw new Error("Missing [CombatDamage] section");this.combatDamage.readIni(e)}readRadiation(){var e=this.ini.getSection("Radiation");if(!e)throw new Error("Missing [Radiation] section");this.radiation.readIni(e)}readGeneral(){var e=this.ini.getSection("General");if(!e)throw new Error("Missing [General] section");this.general.readIni(e)}readAi(){var e=this.ini.getSection("AI");if(!e)throw new Error("Missing [AI] section");this.ai.readIni(e)}readCrateRules(){var e=this.ini.getSection("CrateRules");if(!e)throw new Error("Missing [CrateRules] section");this.crateRules.readIni(e)}readElevationModel(){var e=this.ini.getSection("ElevationModel");if(!e)throw new Error("Missing [ElevationModel] section");this.elevationModel.readIni(e)}readMpDialogSettings(){var e=this.ini.getSection("MultiplayerDialogSettings");if(!e)throw new Error("Missing [MultiplayerDialogSettings] section");this.mpDialogSettings.readIni(e)}readObjectTypes(i,r){let e=this.ini.getSection(i);if(!e)throw new Error(`Missing [${i}] section`);let s=0,a=new Set;e.entries.forEach((e,t)=>{"string"==typeof e?Number.isNaN(Number(t))?this.logger?.debug(`Non-numeric id "${t}" found in rules section [${i}]. Skipping.`):a.has(e)?this.logger?.debug(`Duplicate type "${e}" in rules section [${i}]. Skipping.`):(r.set(s++,e),a.add(e)):this.logger?.debug(`Non-string type found in rules section [${i}]. Skipping.`)})}readColors(){let e=this.ini.getSection("Colors");if(!e)throw new Error("Missing [Colors] section");e.entries.forEach((e,t)=>{var[i,r,e]=e.split(","),e=Color.fromHsv(parseInt(i,10),parseInt(r,10),parseInt(e,10));this.colors.set(t,e)})}readObjects(r,e,s){e.forEach((e,t)=>{var i=this.ini.getSection(e);i?(t=(new ObjectRulesFactory).create(r,i,this.general,t),s.set(e,t)):this.logger?.debug(ObjectType[r]+` type "${e}" has no rules section`)})}readCountries(){this.countryTypes.forEach((e,t)=>{var i=this.ini.getSection(e);if(!i)throw new Error("Missing ini section for country "+e);let r=new CountryRules(t);r.readIni(i),this.countryRules.set(e,r)})}readWarheads(){this.warheadTypes.forEach(e=>{var t=this.ini.getSection(e);t?(t=new WarheadRules(t),this.warheadRules.set(e.toLowerCase(),t)):this.logger?.debug(`Warhead "${e}" has no rules section`)})}readPowerups(){var e=this.ini.getSection("Powerups");if(!e)throw new Error("Missing [Powerups] section");this.powerups.readIni(e)}readTiberiums(){this.tiberiumTypes.forEach((e,t)=>{var i=this.ini.getSection(e);if(!i)throw new Error("Missing rules section for tiberium type "+e);this.tiberiumRules.set(e,new TiberiumRules(t).readIni(i))})}readSuperWeapons(){this.superWeaponTypes.forEach((e,t)=>{var i=this.ini.getSection(e);if(!i)throw new Error("Missing rules section for superweapon type "+e);this.superWeaponRules.set(e,new SuperWeaponRules(t).readIni(i))})}buildWeaponsList(){let e=new Set;e.add(this.general.dropPodWeapon);for(var t of this.superWeaponRules.values())t.weaponType&&e.add(t.weaponType);var r,i;e.add(Weapon.NUKE_PAYLOAD_NAME);for(let i of[...this.buildingRules.values(),...this.aircraftRules.values(),...this.vehicleRules.values(),...this.infantryRules.values()])for(r of[i.deathWeapon,i.primary,i.secondary,i.elitePrimary,i.eliteSecondary,i.occupyWeapon,i.eliteOccupyWeapon,...i.weaponCount?new Array(i.weaponCount).fill(0).map((e,t)=>[i.getWeaponAtIndex(t),i.getEliteWeaponAtIndex(t)]).flat():[]].filter(isNotNullOrUndefined).filter(e=>""!==e))e.add(r);let s=0;for(i of e)this.weaponTypes.set(s++,i)}}!function(e){e[e.Ready=0]="Ready",e[e.Guard=1]="Guard",e[e.Prone=2]="Prone",e[e.Walk=3]="Walk",e[e.FireUp=4]="FireUp",e[e.Down=5]="Down",e[e.Crawl=6]="Crawl",e[e.Up=7]="Up",e[e.FireProne=8]="FireProne",e[e.Idle1=9]="Idle1",e[e.Idle2=10]="Idle2",e[e.Die1=11]="Die1",e[e.Die2=12]="Die2",e[e.Hover=13]="Hover",e[e.Fly=14]="Fly",e[e.FireFly=15]="FireFly",e[e.Tumble=16]="Tumble",e[e.AirDeathStart=17]="AirDeathStart",e[e.AirDeathFalling=18]="AirDeathFalling",e[e.AirDeathFinish=19]="AirDeathFinish",e[e.Tread=20]="Tread",e[e.Swim=21]="Swim",e[e.WetAttack=22]="WetAttack",e[e.WetIdle1=23]="WetIdle1",e[e.WetIdle2=24]="WetIdle2",e[e.WetDie1=25]="WetDie1",e[e.WetDie2=26]="WetDie2",e[e.Deploy=27]="Deploy",e[e.Deployed=28]="Deployed",e[e.DeployedFire=29]="DeployedFire",e[e.DeployedIdle=30]="DeployedIdle",e[e.Undeploy=31]="Undeploy",e[e.Paradrop=32]="Paradrop",e[e.Cheer=33]="Cheer",e[e.Panic=34]="Panic"}(SequenceType=SequenceType||{});const facingByCardinal=new Map([["E",5],["S",3],["W",1],["N",7]]);class SequenceReader{readIni(e){let t=new Map;for(var[i,r]of e.entries){i=SequenceType[i];void 0!==i&&(r=r.split(","),r={type:i,startFrame:Number(r[0]),frameCount:Number(r[1]),facingMult:Number(r[2]),onlyFacing:r[3]?facingByCardinal.get(r[3]):void 0},t.set(i,r))}return t}}!function(e){e[e.None=0]="None",e[e.Global=1]="Global",e[e.Level=2]="Level",e[e.Ambient=3]="Ambient",e[e.Full=4]="Full",e[e.Default=5]="Default"}(LightingType=LightingType||{});class ObjectArt{static getDefaultPalette(e){switch(e){case ObjectType.Building:case ObjectType.Aircraft:case ObjectType.Infantry:case ObjectType.Vehicle:case ObjectType.Projectile:case ObjectType.VoxelAnim:return PaletteType.Unit;case ObjectType.Overlay:return PaletteType.Overlay;case ObjectType.Smudge:case ObjectType.Terrain:return PaletteType.Iso;default:ObjectType.Animation;return PaletteType.Anim}}static getDefaultLighting(e){switch(e){case ObjectType.Animation:return LightingType.None;case ObjectType.Aircraft:case ObjectType.Building:case ObjectType.Infantry:case ObjectType.Vehicle:return LightingType.Ambient;case ObjectType.Projectile:case ObjectType.VoxelAnim:return LightingType.Global;case ObjectType.Overlay:case ObjectType.Smudge:case ObjectType.Terrain:default:return LightingType.Full}}static getDefaultRemapability(e){switch(e){case ObjectType.Aircraft:case ObjectType.Building:case ObjectType.Infantry:case ObjectType.Vehicle:return!0;case ObjectType.Overlay:case ObjectType.Smudge:case ObjectType.Terrain:case ObjectType.Animation:case ObjectType.Projectile:case ObjectType.VoxelAnim:return!1;default:throw new Error("Unknown object type "+e)}}static getDefaultDrawOffset(e){switch(e){case ObjectType.Animation:case ObjectType.Building:case ObjectType.Vehicle:case ObjectType.Infantry:case ObjectType.Overlay:case ObjectType.Smudge:case ObjectType.Projectile:case ObjectType.VoxelAnim:return new Vector2(0,0);case ObjectType.Terrain:case ObjectType.Aircraft:return new Vector2(0,(Coords.ISO_TILE_SIZE+1)/2);default:throw new Error("Unknown object type "+e)}}static getDefaultShadow(e){switch(e){case ObjectType.Overlay:case ObjectType.Building:case ObjectType.Infantry:case ObjectType.Terrain:case ObjectType.Vehicle:case ObjectType.Aircraft:return!0;default:case ObjectType.Smudge:case ObjectType.Animation:case ObjectType.Projectile:case ObjectType.VoxelAnim:return!1}}static getDefaultHeight(e){switch(e){case ObjectType.Building:return 2;case ObjectType.Infantry:case ObjectType.Vehicle:case ObjectType.Aircraft:return 1;default:return 0}}static factory(e,t,i,r){let s=new this(e,t,r);return e===ObjectType.Infantry&&(!(r=r.getString("Sequence"))||(r=i.getSection(r))&&(s.sequences=(new SequenceReader).readIni(r))),s}constructor(e,t,i){this.sequences=new Map,this.dockingOffsets=[],this.type=e,this.rules=t,this.art=i,this.init()}init(){this.image=[ObjectType.Infantry,ObjectType.Vehicle,ObjectType.Aircraft].includes(this.type)?"":this.art.getString("Image"),this.report=this.art.getString("Report")||void 0,this.readRotors(),this.noHva=this.art.getBool("NoHVA"),this.startSound=this.art.getString("StartSound")||void 0,this.readMuzzleFlash(),this.readPaletteAndLightingTypes(),this.readRemapability(),this.readFlatness(),this.readDockingOffsets();var e=this.art.getNumberArray("QueueingCell");this.queueingCell=e.length?new Vector2(e[0],e[1]):void 0,this.demandLoad=this.art.getBool("DemandLoad");var t=this.art.getBool("UseLineTrail"),i=this.art.getNumberArray("LineTrailColor"),e=this.art.getNumber("LineTrailColorDecrement",ObjectArt.DEFAULT_LINE_TRAIL_DEC);t&&i.length?(this.useLineTrail=!0,this.lineTrailColor=i,this.lineTrailColorDecrement=e):this.useLineTrail=!1,this.crater=this.art.getBool("Crater"),this.forceBigCraters=this.art.getBool("ForceBigCraters"),this.scorch=this.art.getBool("Scorch"),this.height=this.art.getNumber("Height",ObjectArt.getDefaultHeight(this.type)),this.isVoxel=this.art.getBool("Voxel"),this.occupyHeight=this.art.getNumber("OccupyHeight",this.height),this.type===ObjectType.Building?this.canHideThings=this.art.getBool("CanHideThings",!0):this.canHideThings=!1,this.canBeHidden=this.art.getBool("CanBeHidden",!0),this.addOccupy=this.readAddRemoveOccupy("AddOccupy"),this.removeOccupy=this.readAddRemoveOccupy("RemoveOccupy"),this.rotates=this.art.getBool("Rotates"),this.toOverlay=this.art.getString("ToOverlay")||void 0}get imageName(){return(this.image||this.rules.imageName)+(this.rules.alternateArcticArt?"A":"")}get cameo(){let e=this.art.getString("Cameo")||ObjectArt.MISSING_CAMEO;return e.toLowerCase()}get altCameo(){let e=this.art.getString("AltCameo")||this.cameo;return e.toLowerCase()}get useTheaterExtension(){return this.art.getBool("Theater")}readPaletteAndLightingTypes(){this.paletteType=PaletteType.Default,this.lightingType=LightingType.Default,(this.rules instanceof OverlayRules?this.rules.noUseTileLandType:void 0)&&(this.paletteType=PaletteType.Iso,this.lightingType=LightingType.Full),this.art.getBool("TerrainPalette")||this.art.getBool("ShouldUseCellDrawer")?this.paletteType=PaletteType.Iso:this.art.getBool("AnimPalette")?(this.paletteType=PaletteType.Anim,this.lightingType=LightingType.None):this.art.getString("Palette")&&(this.paletteType=PaletteType.Custom,this.customPaletteName=this.art.getString("Palette")),this.art.getBool("AltPalette")&&(this.paletteType=PaletteType.Unit),(this.rules instanceof OverlayRules||this.rules instanceof TechnoRules)&&this.rules.wall&&(this.paletteType=PaletteType.Unit,this.lightingType=LightingType.Ambient),(this.rules instanceof TerrainRules||this.rules instanceof TechnoRules)&&this.rules.gate&&(this.paletteType=PaletteType.Unit),this.rules instanceof TerrainRules&&this.rules.spawnsTiberium&&(this.paletteType=PaletteType.Unit,this.lightingType=LightingType.None),this.rules instanceof OverlayRules&&(this.rules.isVeins&&(this.paletteType=PaletteType.Unit,this.lightingType=LightingType.None),this.rules.isVeinholeMonster&&(this.paletteType=PaletteType.Unit,this.lightingType=LightingType.None),this.rules.tiberium&&(this.lightingType=LightingType.None),this.rules.land===LandType.Railroad&&(this.paletteType=PaletteType.Iso,this.lightingType=LightingType.Full),this.rules.crate&&(this.paletteType=PaletteType.Iso,this.lightingType=LightingType.Full)),this.paletteType===PaletteType.Default&&(this.paletteType=ObjectArt.getDefaultPalette(this.type)),this.lightingType===LightingType.Default&&(this.lightingType=ObjectArt.getDefaultLighting(this.type))}readRemapability(){this.remapable=ObjectArt.getDefaultRemapability(this.type),this.art.getBool("TerrainPalette")||this.art.getBool("AnimPalette")?this.remapable=!1:this.rules instanceof ProjectileRules&&this.rules.firersPalette&&(this.remapable=!0)}readFlatness(){let e=!1;this.type===ObjectType.Building||this.type===ObjectType.Animation?e=this.art.getBool("Flat"):this.type===ObjectType.Smudge&&(e=!0),this.rules instanceof OverlayRules&&(this.rules.wall||this.rules.crate||this.rules.isARock||(e=!0)),this.flat=e}readRotors(){var i=this.art.getArray("Rotors");if(i.length){let t=[];for(let e=0;e<i.length;++e){var r=this.art.getNumberArray(`Rotor${e+1}Axis`,void 0,[0,1,0]),r=new Vector3_Vector3(-r[2],-r[0],r[1]).normalize();t.push({name:i[e],axis:r,speed:this.art.getNumber(`Rotor${e+1}Rate`)||void 0,idleSpeed:this.art.getNumber(`Rotor${e+1}IdleRate`)||void 0})}t.length&&(this.rotors=t)}}readMuzzleFlash(){let e=0,t="MuzzleFlash"+e,i=[];for(;this.art.has(t);){var[r,s]=this.art.getNumberArray(t);i.push({x:r,y:s}),e++,t="MuzzleFlash"+e}this.muzzleFlash=i.length?i:void 0}readDockingOffsets(){if(this.type===ObjectType.Building){var t=this.rules.numberOfDocks;for(let e=0;e<t;e++){var[i,r,s]=this.art.getNumberArray("DockingOffset"+e,/,\s*/,[0,0,0]);this.dockingOffsets.push(new Vector3_Vector3(i,s,r))}}}readAddRemoveOccupy(e){let t=0,i=[];for(;;){var r=this.art.getNumberArray(e+ ++t);if(!r.length)break;i.push(new Vector2(r[0],r[1]))}return i}get bibShape(){return this.art.getString("BibShape")}get foundation(){let e=this.art.getString("Foundation","1x1");var[t,i]=e.split(/x/i);return{width:parseInt(t,10),height:parseInt(i,10)}}get foundationCenter(){return new Vector2(Math.floor(this.foundation.width/2-.5),Math.floor(this.foundation.height/2-.5))}getDrawOffset(){if(this.rules instanceof TerrainRules&&this.rules.spawnsTiberium)return new Vector2(0,0);let e=ObjectArt.getDefaultDrawOffset(this.type);return this.rules instanceof OverlayRules&&this.rules.isARock&&(e.y+=(Coords.ISO_TILE_SIZE+1)/2),e}get hasShadow(){return this.art.getBool("Shadow",ObjectArt.getDefaultShadow(this.type))&&!this.rules.noShadow}get turretOffset(){return this.art.getNumber("TurretOffset")}get facings(){return this.art.getNumber("Facings",8)}get walkFrames(){return this.art.getNumber("WalkFrames")}get firingFrames(){return this.art.getNumber("FiringFrames")}get standingFrames(){return this.art.getNumber("StandingFrames",1)}get startWalkFrame(){return this.art.getNumber("StartWalkFrame",0)}get startStandFrame(){return this.art.getNumber("StartStandFrame",this.walkFrames*this.facings)}get startFiringFrame(){return this.art.getNumber("StartFiringFrame",(this.walkFrames+this.standingFrames)*this.facings)}get isFlamingGuy(){return this.art.getBool("IsFlamingGuy")}get runningFrames(){return this.art.getNumber("RunningFrames")}get crawls(){return this.art.getBool("Crawls",!0)}get primaryFireFlh(){return new FlhCoords(this.art.getNumberArray("PrimaryFireFLH"))}get elitePrimaryFireFlh(){var e=this.art.getNumberArray("ElitePrimaryFireFLH");return e.length?new FlhCoords(e):this.primaryFireFlh}get primaryFirePixelOffset(){return this.art.getNumberArray("PrimaryFirePixelOffset")}get secondaryFirePixelOffset(){return this.art.getNumberArray("SecondaryFirePixelOffset")}get secondaryFireFlh(){return new FlhCoords(this.art.getNumberArray("SecondaryFireFLH"))}get eliteSecondaryFireFlh(){var e=this.art.getNumberArray("EliteSecondaryFireFLH");return e.length?new FlhCoords(e):this.secondaryFireFlh}getSpecialWeaponFlh(e){return new FlhCoords(this.art.getNumberArray(`Weapon${e+1}FLH`))}get fireUp(){return this.art.getNumber("FireUp")||this.art.getNumber("DelayedFireDelay")}get isAnimDelayedFire(){return this.art.getBool("IsAnimDelayedFire")}get zShapePointMove(){return this.art.getNumberArray("ZShapePointMove")}get zAdjust(){return this.art.getNumber("ZAdjust")}get trailer(){return this.art.getString("Trailer")}get spawnDelay(){return this.art.getNumber("SpawnDelay",1)}get translucent(){return this.art.getBool("Translucent")}get translucency(){var e=(e=this.art.getNumber("Translucency",0))/25*25;return e/=100}}ObjectArt.DEFAULT_LINE_TRAIL_DEC=16,ObjectArt.MISSING_CAMEO="xxicon";class Art{constructor(e,t,i,r){this.rules=e,this.artIni=t,this.mapFile=i,this.logger=r,this.objectArt=new Map,this.parse()}hasObject(e,t){return this.objectArt.get(t)?.has(e)}getObject(e,t){if(!e)throw new Error(`Must specify an art name for type "${ObjectType[t]}"`);var i=this.objectArt.get(t)?.get(e);return i||(this.logger?.debug(`Missing art for object "${e}"`),new ObjectArt(t,this.rules.hasObject(e,t)?this.rules.getObject(e,t):new ObjectRules(t,new IniSection(e)),new IniSection(e)))}getAnimation(e){return this.getObject(e,ObjectType.Animation)}getProjectile(e){var t=this.rules.getProjectile(e),i=t.imageName;let r=this.artIni.getSection(i);return r||(this.logger?.debug(`Image ${i} (Projectile: ${e}) has no section in art.ini`),r=new IniSection(i)),ObjectArt.factory(t.type,t,this.artIni,r)}getIni(){return this.artIni}parse(){this.rules.allObjectRules.forEach((e,t)=>{let r=new Map;this.objectArt.set(t,r),e.forEach(e=>{var t=this.artIni.getSection(e.imageName),i=this.artIni.getSection(e.name);(t=this.applyUnitMapOverrides(e,this.mapFile,i,t))?(t=ObjectArt.factory(e.type,e,this.artIni,t),r.set(e.name,t)):this.logger?.debug(`${ObjectType[e.type]} "${e.name}" has no art section "${e.imageName}"`)})});let e=[[ObjectType.Animation,this.rules.animationNames]];e.forEach(([r,e])=>{let s=new Map;this.objectArt.set(r,s),e.forEach(e=>{var t,i=this.artIni.getSection(e);i?(t=new ObjectRules(r,new IniSection(e)),i=new ObjectArt(r,t,i),s.set(e,i)):this.logger?.debug(ObjectType[r]+` "${e}" has no art section`)})})}applyUnitMapOverrides(e,t,r,s){if([ObjectType.Infantry,ObjectType.Vehicle,ObjectType.Aircraft].includes(e.type)&&!!t?.getSection(e.name)?.getString("Image")&&r){let i=r.clone();s?.entries.forEach((e,t)=>{i.set(t,e)}),s=i,this.logger?.debug(`${ObjectType[e.type]} "${e.name}": `+`Using merged art sections ${e.name} and `+e.imageName)}return s}}class Country{static factory(e,t){return new this(t.getCountry(e))}constructor(e){this.rules=e}get id(){return this.rules.id}get side(){return this.rules.side}get name(){return this.rules.name}isPlayable(){return this.rules.multiplay&&!this.rules.multiplayPassive}hasVeteranUnit(e,t){let i=[];switch(e){case ObjectType.Aircraft:i=this.rules.veteranAircraft;break;case ObjectType.Infantry:i=this.rules.veteranInfantry;break;case ObjectType.Vehicle:i=this.rules.veteranUnits;break;default:throw new Error(`Unsupported object type "${ObjectType[e]}"`)}return i.includes(t)}}class BuildingEvacuateEvent{constructor(e,t){this.target=e,this.player=t,this.type=EventType.BuildingEvacuate}}class GarrisonTrait{constructor(e,t,i){this.building=e,this.evacThreshold=t,this.maxOccupants=i,this.units=[]}isOccupied(){return!!this.units.length}canBeOccupied(){return this.building.healthTrait.health>100*this.evacThreshold}[NotifyDamage.onDamage](e,t){e.healthTrait.health<=100*this.evacThreshold&&this.evacuate(t)}[NotifyDestroy.onDestroy](e,t,i,r){if(r){for(var s of this.units)s.deathType=e.deathType,t.destroyObject(s,i,!0);this.units=[]}else this.evacuate(t)}getHash(){return fnv32a(this.units.map(e=>e.getHash()))}debugGetState(){return{units:this.units.map(e=>e.debugGetState())}}dispose(){this.building=void 0}evacuate(r,s=!1){let a=this.building,n=this.units;if(n.length){let e=new Map;for(var t of n)e.set(t.rules.speedType,(e.get(t.rules.speedType)||[]).concat(t));for(let[t,i]of e){var o,l=new RadialTileFinder(r.map.tiles,r.map.mapBounds,a.tile,a.art.foundation,1,1,e=>0<r.map.terrain.getPassableSpeed(e,t,!0,!1)&&Math.abs(e.z-a.tile.z)<2&&!r.map.terrain.findObstacles({tile:e,onBridge:void 0},i[0]).length).getNextTile();for(o of i){var h=n.indexOf(o);l?(n.splice(h,1),r.unlimboObject(o,l),o.onBridge=r.map.tileOccupation.getBridgeOnTile(l)?.isLowBridge()??!1,o.position.tileElevation=0,o.unitOrderTrait.addTask(new ScatterTask(r))):s||(r.destroyObject(o,{player:o.owner}),n.splice(h,1))}}var i=a.owner;n.length||a.isDestroyed||r.changeObjectOwner(a,r.getCivilianPlayer()),r.events.dispatch(new BuildingEvacuateEvent(a,i))}}}class TurretTrait{constructor(){this.facing=0,this.desiredFacing=0}isRotating(){return this.facing!==this.desiredFacing}[NotifySpawn.onSpawn](e){e.isUnit()&&(this.facing=this.desiredFacing=e.direction)}[NotifyTick_NotifyTick.onTick](e){this.desiredFacing!==this.facing&&(e=e.rules.rot,this.facing=FacingUtil.tick(this.facing,this.desiredFacing,e||Number.POSITIVE_INFINITY).facing)}}class BuildStatusChangeEvent{constructor(e,t){this.target=e,this.status=t,this.type=EventType.BuildStatusChange}}class PowerLowEvent{constructor(e){this.target=e,this.type=EventType.PowerLow}}class PowerRestoreEvent{constructor(e){this.target=e,this.type=EventType.PowerRestore}}class PowerChangeEvent{constructor(e,t,i){this.target=e,this.power=t,this.drain=i,this.type=EventType.PowerChange}}!function(e){e[e.Low=0]="Low",e[e.Normal=1]="Normal"}(PowerLevel=PowerLevel||{});class PowerTrait{constructor(e){this.player=e,this.power=0,this.drain=0,this.level=PowerLevel.Normal,this.blackoutFrames=0,this.powerByObject=new Map}isLowPower(){return this.level===PowerLevel.Low}setBlackoutFor(e,t){var i=0<this.blackoutFrames;this.blackoutFrames=e,i||this.updateLevel(t)}updateBlackout(e){0<this.blackoutFrames&&(this.blackoutFrames--,this.blackoutFrames<=0&&this.updateLevel(e))}getBlackoutDuration(){return this.blackoutFrames}updateFrom(t,i,r){var s=t.rules.power;if(s){if(s<0)"add"!==i&&"remove"!==i||(this.drain+="add"===i?-s:s);else{let e=0;if("add"===i){var a=Math.ceil(s*t.healthTrait.health/100);this.powerByObject.set(t,a),e=a}else if("update"===i||"remove"===i){a=this.powerByObject.get(t);if(void 0===a)throw new Error("Cannot update power before add.");e="update"===i?(s=Math.ceil(s*t.healthTrait.health/100),this.powerByObject.set(t,s),s-a):(this.powerByObject.delete(t),-a)}this.power+=e}this.updateLevel(r),r.traits.filter(NotifyPower).forEach(e=>{e[NotifyPower.onPowerChange](this.player,r)}),r.events.dispatch(new PowerChangeEvent(this.player,this.power,this.drain))}}updateLevel(t){var e=this.level;this.level=this.power>=this.drain&&!this.blackoutFrames?PowerLevel.Normal:PowerLevel.Low,this.level!==e&&(e===PowerLevel.Normal&&this.level===PowerLevel.Low&&(t.traits.filter(NotifyPower).forEach(e=>{e[NotifyPower.onPowerLow](this.player,t)}),t.events.dispatch(new PowerLowEvent(this.player))),e===PowerLevel.Low&&this.level===PowerLevel.Normal&&(t.traits.filter(NotifyPower).forEach(e=>{e[NotifyPower.onPowerRestore](this.player,t)}),t.events.dispatch(new PowerRestoreEvent(this.player))))}getHash(){return fnv32a([this.power,this.drain])}debugGetState(){return{power:this.power,drain:this.drain}}dispose(){this.player=void 0,this.powerByObject.clear()}}class PoweredTrait{constructor(e){this.obj=e,this.turnedOn=!0}setTurnedOn(e){this.turnedOn=e}isCharged(){return!!this.obj.isBuilding()&&!!this.obj.overpoweredTrait?.hasChargersToPowerOn()}isPoweredOn(e=!1){return!(!this.obj||!this.turnedOn)&&(!(e||!this.isCharged())||(!this.obj.rules.power&&this.obj.rules.needsEngineer?!this.obj.owner.isNeutral:!!this.obj.owner.powerTrait&&this.obj.owner.powerTrait?.level!==PowerLevel.Low))}dispose(){this.obj=void 0}}class EventDispatcher{constructor(){this.listeners=new Set}subscribe(e){this.listeners.add(e)}subscribeOnce(i){let r=(e,t)=>{i(e,t),this.unsubscribe(r),r=void 0};this.subscribe(r)}unsubscribe(e){this.listeners.delete(e)}dispatch(t,i){this.listeners.forEach(e=>e(i,t))}asEvent(){return this}}!function(e){e[e.Structures=0]="Structures",e[e.Armory=1]="Armory",e[e.Infantry=2]="Infantry",e[e.Vehicles=3]="Vehicles",e[e.Aircrafts=4]="Aircrafts",e[e.Ships=5]="Ships"}(QueueType=QueueType||{}),function(e){e[e.Idle=0]="Idle",e[e.Active=1]="Active",e[e.OnHold=2]="OnHold",e[e.Ready=3]="Ready"}(QueueStatus=QueueStatus||{});class ProductionQueue{get onUpdate(){return this._onUpdate.asEvent()}constructor(e,t,i){this.type=e,this._maxSize=t,this.maxItemQuantity=i,this.items=[],this.size=0,this._status=QueueStatus.Idle,this._onUpdate=new EventDispatcher}get status(){return this._status}set status(e){var t=this._status;(this._status=e)!==t&&this._onUpdate.dispatch(this)}get maxSize(){return this._maxSize}set maxSize(e){var t=this.size;this.size=Math.min(e,this.size);let i=0,r=0;for(;i<=this.size&&r<this.items.length;){let e=this.items[r];i+=e.quantity,i>this.size&&(e.quantity-=i-this.size),0<e.quantity&&r++}this._maxSize=e,this.items[r]&&this.items.splice(r),t!==this.size&&(this.size||(this._status=QueueStatus.Idle),this._onUpdate.dispatch(this))}get currentSize(){return this.size}find(t){return this.items.filter(e=>e.rules===t)}getFirst(){return this.items[0]}getAll(){return[...this.items]}push(e,t,i){t=Math.min(this.maxSize-this.size,t);var r=this.find(e).reduce((e,t)=>e+t.quantity,0);(t=Math.min(this.maxItemQuantity-r,t))&&(this.items[this.items.length-1]?.rules===e?this.items[this.items.length-1].quantity+=t:this.items.push({rules:e,quantity:t,creditsEach:i,creditsSpent:0,creditsSpentLeftover:0,progress:0}),this.size+=t,this._status===QueueStatus.Idle&&(this._status=QueueStatus.Active),this._onUpdate.dispatch(this))}insertAfterFirst(t,i,r){i=Math.min(this.maxSize-this.size,i);var s=this.find(t).reduce((e,t)=>e+t.quantity,0);if(i=Math.min(this.maxItemQuantity-s,i))if(this.items.length){let e=this.items[0];var a=e.quantity,s=Math.max(0,a-1);e.quantity=1;const n=[e];a=this.items.slice(1);n.push({rules:t,quantity:i,creditsEach:r,creditsSpent:0,creditsSpentLeftover:0,progress:0}),0<s&&n.push({rules:e.rules,quantity:s,creditsEach:e.creditsEach,creditsSpent:0,creditsSpentLeftover:0,progress:0}),n.push(...a),this.items=n,this.size+=i,this._status===QueueStatus.Idle&&(this._status=QueueStatus.Active),this._onUpdate.dispatch(this)}else this.push(t,i,r)}pop(e,t){this.remove(e,t,!1)}shift(e,t){this.remove(e,t,!0)}remove(e,t,i){let r=this.find(e);if(!r.length)throw new Error(`Can't remove non-existent item ${e.name} from queue `+QueueType[this.type]);var s;if(r.reduce((e,t)=>e+t.quantity,0)<t)throw new Error(`Attempted to remove a quantity larger than the one in queue (${e.name})`);let a=t;for(;0<a;){let e=i?r.shift():r.pop();e.quantity<=a?(s=this.getFirst()===e,this.items.splice(this.items.indexOf(e),1),s&&(this._status=QueueStatus.Active),a-=e.quantity):(e.quantity-=a,a=0)}this.size-=t,t&&(this.size||(this._status=QueueStatus.Idle),this._onUpdate.dispatch(this))}notifyUpdated(){this._onUpdate.dispatch(this)}}const LosHelper_isGameObject=e=>void 0!==e.position;class LosHelper{constructor(e,t){this.tiles=e,this.tileOccupation=t}hasLineOfSight(t,i,r){var s=r.warhead.rules.wall||!r.projectileRules.subjectToWalls,a=r.projectileRules.subjectToCliffs,n=r.rules.spawner;let o=0,l=!1;if(!s||a||n){var h,c,r=LosHelper_isGameObject(t)?t.tile:t,i=LosHelper_isGameObject(i)?i.isBuilding()?i.centerTile:i.tile:i;let e=r.z;a&&LosHelper_isGameObject(t)&&t.isUnit()&&t.onBridge&&(e+=this.tileOccupation.getBridgeOnTile(r)?.tileElevation??0);for({x:h,y:c}of bresenham(r.rx,r.ry,i.rx,i.ry)){var d=this.tiles.getByMapCoords(h,c);if(!d)return!1;if(!s&&d.landType===LandType.Wall)return!1;if(a)if(d.landType===LandType.Cliff){if(d.z>e)return!1;l=!0}else{if(d.z>e&&l)return!1;l=!1}if(n&&o<2&&this.tileOccupation.getBridgeOnTile(d)?.isHighBridge())return!1;o++}}return!0}}const STRAFE_CLOSE_ENOUGH=2,BOMBER_RETURN_TILES=7;class MoveInWeaponRangeTask extends MoveTask{constructor(e,t,i,r){super(e,t instanceof GameObject?t.isBuilding()?t.centerTile:t.tile:t,i,{pathFinderIgnoredBlockers:t instanceof GameObject&&0<r.range?[t]:void 0}),this.target=t,this.weapon=r,this.recalcMinRange=!0,this.cancelRequested=!1,this.bomberInitialLock=!1,this.rangeHelper=new RangeHelper(e.map.tileOccupation),this.losHelper=new LosHelper(e.map.tiles,e.map.tileOccupation)}onStart(i){let e=this.target,r=this.game.map;if(e instanceof GameObject&&e.isBuilding()&&i.rules.movementZone!==MovementZone.Fly){let t=e.tile;var s=e instanceof GameObject?e.getFoundation():{width:1,height:1},s=new RadialTileFinder(r.tiles,r.mapBounds,t,s,1,5,e=>0<r.terrain.getPassableSpeed(e,i.rules.speedType,i.isInfantry(),!1)&&Math.abs(e.z-t.z)<2).getNextTile();s&&this.rangeHelper.tileDistance(e,s)>Math.SQRT2&&this.updateTarget(s,!1)}this.bomberInitialLock=this.isCloseEnoughToDest(i,i.tile),super.onStart(i)}cancel(){this.bomberManeuverTile?this.cancelRequested=!0:super.cancel()}shouldAirStrafe(e){return e.rules.movementZone===MovementZone.Fly&&e.rules.locomotor===LocomotorType.Aircraft&&e.rules.fighter&&1<this.weapon.projectileRules.iniRot}isBombingRun(e){return e.rules.movementZone===MovementZone.Fly&&e.rules.locomotor===LocomotorType.Aircraft&&this.weapon.projectileRules.iniRot<=1}isAirStrafeCloseEnough(e){return this.rangeHelper.tileDistance(e,this.targetTile)<Math.min(this.weapon.range,STRAFE_CLOSE_ENOUGH)}bomberCanReturn(e){return!this.bomberManeuverTile||this.rangeHelper.tileDistance(e,this.bomberManeuverTile)<=1}findStrafeDestination(t,i){let e=new RandomTileFinder(this.game.map.tiles,this.game.map.mapBounds,i,this.weapon.range,this.game,e=>this.rangeHelper.isInWeaponRange(t,i,this.weapon,this.game.rules,e));return e.getNextTile()}hasReachedDestination(e){return super.hasReachedDestination(e)||this.canStopAtTile(e,e.tile,e.onBridge)}canStopAtTile(t,e,i){if(t.zone!==ZoneType.Air&&this.target instanceof GameObject&&this.game.map.tileOccupation.isTileOccupiedBy(e,this.target)&&(!this.target.isUnit()||this.target.tile===e&&this.target.moveTrait.moveState!==MoveState.Moving&&this.target.position.subCell===t.position.subCell))return!1;if(t.zone!==ZoneType.Air){if(!super.canStopAtTile(t,e,i))return!1}else if(this.game.map.tileOccupation.getAirObjectsOnTile(e).filter(e=>e.isUnit()&&e.moveTrait.moveState!==MoveState.Moving&&e!==t).length)return!1;return!(this.isBombingRun(t)&&!this.bomberCanReturn(e))&&(!!this.isCancelling()||this.isCloseEnoughToDest(t,e))}isCloseEnoughToDest(e,t){if(e.rules.balloonHover&&!e.rules.hoverAttack)return this.rangeHelper.isInTileRange(t,this.target,0,0);if(this.weapon.rules.cellRangefinding||!e.isInfantry())return this.rangeHelper.isInWeaponRange(e,this.target,this.weapon,this.game.rules,t)&&this.losHelper.hasLineOfSight(t,this.target,this.weapon);var i=e.zone===ZoneType.Air?e.position.computeSubCellOffset(e.position.desiredSubCell):e.position.getTileOffset(),{minRange:r,range:s}=this.rangeHelper.computeWeaponRangeVsTarget(t,this.target,this.weapon,this.game.rules),i=Coords.tile3dToWorld(t.rx+i.x/Coords.LEPTONS_PER_TILE,t.ry+i.y/Coords.LEPTONS_PER_TILE,t.z+e.position.tileElevation);return(e.isUnit()&&e.rules.movementZone===MovementZone.Fly?this.rangeHelper.isInRange2(i,this.target,r,s):this.rangeHelper.isInRange3(i,this.target,r,s))&&this.losHelper.hasLineOfSight(t,this.target,this.weapon)}findRelocationTile(t,i,r){if(r.rules.movementZone!==MovementZone.Fly)return super.findRelocationTile(t,i,r);{i=this.game.map;let e=new RandomTileFinder(i.tiles,i.mapBounds,t,1,this.game,e=>this.isCancelling()||this.isCloseEnoughToDest(r,e));return e.getNextTile()}}retarget(e,t){var i=e instanceof GameObject?e.isBuilding()?e.centerTile:e.tile:e;this.bomberManeuverTile?this.bomberQueuedTargetTile=i:(this.updateTarget(i,t),this.recalcMinRange=!0),this.target=e,this.options?.ignoredBlockers&&(this.options.ignoredBlockers=e instanceof GameObject?[e]:void 0),this.options??(this.options={}),this.options.pathFinderIgnoredBlockers=e instanceof GameObject?[e]:void 0}onTick(s){if(this.recalcMinRange){this.recalcMinRange=!1;var e=this.findMinRangeRelocationTile(s,this.targetTile);if(e!==this.targetTile){if(!e)return this.cancel(),!1;this.updateTarget(e,!!e.onBridgeLandType)}}if(this.shouldAirStrafe(s)&&!this.isCancelling()&&(this.updateTarget(this.target instanceof GameObject?this.target.isBuilding()?this.target.centerTile:this.target.tile:this.target,!1),!this.isAirStrafeCloseEnough(s)||(a=this.findStrafeDestination(s,this.targetTile))&&this.updateTarget(a,!1)),this.isBombingRun(s)&&!this.isCancelling()&&(!s.ammo||this.weapon.getBurstsFired()||this.bomberInitialLock)&&!this.bomberManeuverTile){this.bomberInitialLock=!1;let e=s.position.getMapPosition();var a=this.target instanceof GameObject?this.target.isBuilding()?this.target.centerTile:this.target.tile:this.target;let t=new Vector2(a.rx+.5,a.ry+.5).clone().multiplyScalar(Coords.LEPTONS_PER_TILE).sub(e),i=t.length();i||(t.copy(FacingUtil.toMapCoords(s.direction)),i=Number.EPSILON);let r=e.clone().add(t.setLength(i+BOMBER_RETURN_TILES*Coords.LEPTONS_PER_TILE));a=r.multiplyScalar(1/Coords.LEPTONS_PER_TILE).floor(),a=bresenham(a.x,a.y,s.tile.rx,s.tile.ry);if(!a.length)throw new Error("Bresenham returned no tiles");a=a[0];this.bomberManeuverTile=this.game.map.tiles.getByMapCoords(a.x,a.y)??this.game.map.tiles.getPlaceholderTile(a.x,a.y),this.options.allowOutOfBoundsTarget=!0,this.updateTarget(this.bomberManeuverTile,!1)}return this.bomberManeuverTile&&this.bomberCanReturn(s.tile)&&(this.bomberManeuverTile=void 0,this.bomberQueuedTargetTile&&(this.updateTarget(this.bomberQueuedTargetTile,!1),this.recalcMinRange=!0,this.bomberQueuedTargetTile=void 0)),this.cancelRequested&&(this.bomberManeuverTile||(this.cancelRequested=!1,this.cancel())),!!(this.isBombingRun(s)&&this.isCancelling()&&this.forceCancel(s))||super.onTick(s)}forceCancel(e){return!this.bomberManeuverTile&&super.forceCancel(e)}findMinRangeRelocationTile(e,t){var{minRange:i,range:r}=this.rangeHelper.computeWeaponRangeVsTarget(e,this.target,this.weapon,this.game.rules);return e.rules.locomotor===LocomotorType.Chrono?this.rangeHelper.isInRange(e,this.target,r-1,r,this.weapon.rules.cellRangefinding)?t:this.findTileInRange(e,t,r-1,2*r)??t:this.rangeHelper.isInRange(e,this.target,i,Number.POSITIVE_INFINITY,this.weapon.rules.cellRangefinding)?t:this.findTileInRange(e,t,2*i,r-i)}findTileInRange(t,e,i,r){let s=this.game.map;var a,i=new Vector2(t.tile.rx-e.rx,t.tile.ry-e.ry).setLength(i).floor().add(new Vector2(e.rx,e.ry));let n;for(a of bresenham(i.x,i.y,e.rx,e.ry))if(n=s.tiles.getByMapCoords(a.x,a.y),n)break;if(n){let e=new RadialTileFinder(s.tiles,s.mapBounds,n,{width:1,height:1},0,r,e=>this.rangeHelper.isInWeaponRange(t,this.target,this.weapon,this.game.rules,e)&&this.losHelper.hasLineOfSight(e,this.target,this.weapon)&&0<s.terrain.getPassableSpeed(e,t.rules.speedType,t.isInfantry(),!!e.onBridgeLandType)&&!s.terrain.findObstacles({tile:e,onBridge:!!e.onBridgeLandType},t).length);return e.getNextTile()}}}class TaskRunner{tick(e,t){this.tickChildren(e,t)}startTask(e,t){if(e.status!==TaskStatus.NotStarted)throw new Error("Attempted to start a task with status "+e.status);e.status=TaskStatus.Running,e.onStart(t)}tickTask(e,t){let i=this.tickChildren(e.children,t);var r=e.children.find(e=>e.blocking);if(!i&&r)return!1;if(!t.isSpawned)return!1;if(e.status===TaskStatus.NotStarted)throw new Error("Attempted tick on a non-started task");if(e.isRunning()||e.isCancelling()){var s=e.isCancelling(),a=!!e.waitingForChildrenToFinish||e.onTick(t);e.children.length&&!r&&a&&(i=e.children.every(e=>e.status===TaskStatus.Cancelled||e.status===TaskStatus.Finished),e.waitingForChildrenToFinish=!i);a=a&&i;return a&&(e.onEnd(t),e.status=s?TaskStatus.Cancelled:TaskStatus.Finished),a}return!0}tickChildren(r,s){let a=!0;if(r.length){let t=new Set,i;for(;s.isSpawned&&(i=r.find(e=>!t.has(e)));){let e;if(i.status===TaskStatus.NotStarted&&this.startTask(i,s),i.status===TaskStatus.Running||i.status===TaskStatus.Cancelling)e=!0===this.tickTask(i,s);else{if(i.status!==TaskStatus.Cancelled)throw new Error("Unhandled task status "+TaskStatus[i.status]);e=!0}if(e){var n=r.indexOf(i);-1!==n&&r.splice(n,1)}else{if(a=!1,i.blocking)break;t.add(i)}}}return a}}class Target{constructor(e,t,i){this.tileOccupation=i,this.isOre=!1,e?e.isOverlay()&&e.isBridge()?(this.bridge=e,this.tile=t):e.isOverlay()&&e.isTiberium()?(this.isOre=!0,this.tile=e.tile):(this.obj=e,this.tile=e.isBuilding()?e.centerTile:e.tile):(t.landType===LandType.Tiberium&&(this.isOre=!0),this.tile=t)}equals(e){return this.obj===e.obj&&this.tile===e.tile&&this.bridge===e.bridge&&this.isOre===e.isOre}getWorldCoords(){return this.obj?this.obj.position.worldPosition:Coords.tile3dToWorld(this.tile.rx+.5,this.tile.ry+.5,this.tile.z+(this.bridge?.tileElevation??0))}isBridge(){return!this.obj&&!!this.bridge}getBridge(){return this.bridge||(this.obj?.isUnit()&&this.obj.onBridge?this.tileOccupation.getBridgeOnTile(this.obj.tile):void 0)}}const SCAN_TARGET_FOUNDATION_ADJUST=3;!function(e){e[e.Idle=0]="Idle",e[e.CheckRange=1]="CheckRange",e[e.PrepareToFire=2]="PrepareToFire",e[e.FireUp=3]="FireUp",e[e.Firing=4]="Firing",e[e.JustFired=5]="JustFired"}(AttackState=AttackState||{});class AttackTrait{constructor(e,t){this.disabled=!1,this.attackState=AttackState.Idle,this.passiveScanCooldownTicks=0,this.taskRunner=new TaskRunner,this.distributedFireHistory=new Map,this.rangeHelper=new RangeHelper(t),this.losHelper=new LosHelper(e,t)}isIdle(){return this.attackState===AttackState.Idle}isDisabled(){return this.disabled}setDisabled(e){this.disabled=e}isOnCooldown(e){let t=[e.primaryWeapon,e.secondaryWeapon],i=e.armedTrait?.getDeployFireWeapon();return i?.rules.areaFire&&!i.rules.fireOnce&&(t=t.filter(e=>e!==i)),t.some(e=>0<(e?.getCooldownTicks()??0))}expirePassiveScanCooldown(){this.passiveScanCooldownTicks=0}increasePassiveScanCooldown(e){this.passiveScanCooldownTicks+=e}cancelOpportunityFire(){this.opportunityFireTask?.cancel()}getOpportunityFireTask(){return this.opportunityFireTask}selectDefaultWeapon(e){let i;if((e.isInfantry()||e.isVehicle())&&e.rules.deployFire){let t=e.armedTrait?.getDeployFireWeapon();i=e.deployerTrait?.isDeployed()?t&&!t.rules.areaFire?t:void 0:[e.primaryWeapon,e.secondaryWeapon].find(e=>e!==t)}else i=e.isBuilding()&&e.garrisonTrait?e.garrisonTrait.isOccupied()?e.owner.country.side===SideType.GDI?e.primaryWeapon:e.secondaryWeapon??e.primaryWeapon:void 0:e.isBuilding()&&e.overpoweredTrait?e.overpoweredTrait.getWeapon():e.primaryWeapon;return i}selectWeaponVersus(e,t,i,r=!1,s=!1){var a=t.tile;const n=t instanceof Target?t.obj:t;t=this.getAvailableWeapons(e,s,n?.isOverlay()||r&&!n);return this.selectWeaponFromList(e,n,a,t,i,r,s,!1)}selectWeaponFromList(e,t,i,r,s,a,n,o){if((!t?.isInfantry()&&!t?.isVehicle()||!t.disguiseTrait||this.canAttackThroughDisguise(e,t,t.disguiseTrait,s,a,n,o))&&(t?.isBuilding()&&t.overpoweredTrait&&t.owner===e.owner&&r.find(e=>e.warhead.rules.electricAssault)&&(r=r.filter(e=>e.warhead.rules.electricAssault)),!(n&&t?.isAircraft()&&t.missileSpawnTrait&&t.zone!==ZoneType.Air))){var l=t?.isTechno()?t.rules.armor:void 0;for(const h of r)if(h.targeting.canTarget(t,i,s,a,n)&&(void 0===l||this.checkArmor(h.warhead.rules,l,n)))return h}}getAvailableWeapons(e,t,i){let r;var s;return r=(e.isInfantry()||e.isVehicle())&&e.rules.deployFire&&e.armedTrait?(s=e.armedTrait.getDeployFireWeapon(),[e.deployerTrait?.isDeployed()?s.rules.areaFire?void 0:s:s===e.secondaryWeapon?e.primaryWeapon:e.secondaryWeapon]):e.isBuilding()&&e.garrisonTrait?e.garrisonTrait.isOccupied()?[e.owner.country.side===SideType.GDI?e.primaryWeapon:e.secondaryWeapon??e.primaryWeapon]:[]:e.isBuilding()&&e.overpoweredTrait?[e.overpoweredTrait.getWeapon()]:i||t?[e.primaryWeapon,!i&&t&&e.secondaryWeapon?e.secondaryWeapon:void 0]:[e.primaryWeapon,e.secondaryWeapon],r.filter(e=>e&&!e.rules.neverUse)}canAttackThroughDisguise(e,t,i,r,s,a,n){if(!s&&i.hasTerrainDisguise()&&!r.areFriendly(e,t)&&!e.owner.sharedDetectDisguiseTrait?.has(t))return!1;if(a){if(n&&t.moveTrait.isIdle()&&!e.rules.detectDisguise&&!e.owner.sharedDetectDisguiseTrait?.has(t)&&!r.areFriendly(t,e))return!1;i=i.getDisguise();if(i?.owner&&!e.rules.detectDisguise&&!e.owner.sharedDetectDisguiseTrait?.has(t)&&(i.owner===e.owner||r.alliances.areAllied(e.owner,i.owner)))return!1}return!0}checkArmor(e,t,i){var r=e.ivanBomb||e.bombDisarm||e.nukeMaker?1:e.verses.get(t);return void 0===r?(console.warn(`Unhandled ArmorType ${ArmorType[t]} in warhead ${e.name} verses`),!1):!(100*r<=(i?1:0))}createAttackTask(e,t,i,r,s){return new AttackTask(e,e.createTarget(t,i),r,s)}[NotifyTick_NotifyTick.onTick](a,n){if(!this.isDisabled()){if(this.opportunityFireTask&&(!a.unitOrderTrait.hasTasks()||a.isUnit()&&!a.unitOrderTrait.getTasks()[0].preventOpportunityFire||(a.unitOrderTrait.getTasks()[0]instanceof AttackTask?this.opportunityFireTask=void 0:this.opportunityFireTask.cancel()),this.opportunityFireTask&&(c=[this.opportunityFireTask],this.taskRunner.tick(c,a),c.length||(this.opportunityFireTask=void 0))),!this.opportunityFireTask&&this.retaliateTarget){var o=this.retaliateTarget;this.retaliateTarget=void 0;let e;!a.unitOrderTrait.hasTasks()&&n.isValidTarget(o)&&(e=this.selectWeaponVersus(a,o,n,!1))&&a.unitOrderTrait.addTask(this.createAttackTask(n,o,o.tile,e,{holdGround:a.rules.movementZone===MovementZone.Fly}))}if(!this.opportunityFireTask&&this.shouldPassiveAcquire(a))if(0<this.passiveScanCooldownTicks)this.passiveScanCooldownTicks--;else{this.passiveScanCooldownTicks=a.guardMode?n.rules.general.guardAreaTargetingDelay:n.rules.general.normalTargetingDelay;let e=this.selectDefaultWeapon(a);var l,h,c=a.unitOrderTrait.hasTasks();let t=void 0,i,r;!c&&a.guardMode&&e&&a.owner.isCombatant()&&(t=a.armedTrait?.computeGuardScanRange(e),i=a.guardArea?.tile,r=50);let s=!1;!e||(o=this.scanForTarget(a,e,n,t,i)).target&&({target:l,weapon:h}=o,l=this.createAttackTask(n,l,l.tile,h,{holdGround:c||!a.guardMode,disallowTurning:c,leashTiles:r,passive:!0}),c?this.opportunityFireTask=l:a.unitOrderTrait.addTask(l),s=!0,c||!a.guardMode||a.guardArea||(a.guardArea={tile:a.tile,onBridge:!!a.isUnit()&&a.onBridge}),s&&!c&&a.unitOrderTrait[NotifyTick_NotifyTick.onTick](a,n)),s||c||!a.secondaryWeapon?.warhead.rules.electricAssault||(e=a.secondaryWeapon,(h=this.scanForTarget(a,e,n,void 0,void 0,!0)).target&&({target:l,weapon:h}=h,h=this.createAttackTask(n,l,l.tile,h,{passive:!0}),a.unitOrderTrait.addTask(h),s=!0)),!s&&!c&&a.guardArea&&a.isUnit()&&a.moveTrait&&!a.moveTrait.isDisabled()&&a.guardArea.tile!==a.tile&&a.unitOrderTrait.addTasks(new MoveTask(n,a.guardArea.tile,a.guardArea.onBridge),new CallbackTask(()=>{[MoveResult.Success,MoveResult.CloseEnough].includes(a.moveTrait.lastMoveResult)||a.resetGuardModeToIdle(),a.guardArea=void 0}))}}}[NotifyDamage.onDamage](e,t,i,r){this.isDisabled()||!this.retaliateTarget&&!this.opportunityFireTask&&r&&r.obj&&r.weapon&&this.shouldRetaliate(e,t,i,r.obj,r.weapon.warhead)&&(this.retaliateTarget=r.obj)}[NotifyTeleport.onBeforeTeleport](e,t,i,r){r||(this.attackState=AttackState.Idle,this.currentTarget=void 0,this.retaliateTarget=void 0,this.opportunityFireTask=void 0)}shouldPassiveAcquire(e){if(!e.owner.isCombatant()&&e.rules.needsEngineer||!e.rules.canPassiveAquire||!e.primaryWeapon||e.ammoTrait&&!e.ammoTrait.ammo&&e.rules.manualReload)return!1;if(e.mindControllerTrait?.isAtCapacity())return!1;var t=e.rules.opportunityFire||e.rules.balloonHover&&e.unitOrderTrait.getCurrentTask()?.isAttackMove;if(e.isUnit()&&t){if(e.unitOrderTrait.hasTasks()&&e.unitOrderTrait.getTasks()[0].preventOpportunityFire)return!1}else if(e.unitOrderTrait.hasTasks())return!1;return!0}shouldRetaliate(e,t,i,r,s){if(i<1||t.areFriendly(e,r)||!e.rules.canRetaliate||!e.primaryWeapon||e.ammoTrait&&!e.ammoTrait.ammo&&e.rules.manualReload||s.rules.temporal||r.rules.missileSpawn||e.unitOrderTrait.hasTasks()||!t.isValidTarget(r)||(r.isInfantry()||r.isVehicle())&&r.disguiseTrait&&!e.rules.detectDisguise||e.mindControllerTrait?.isAtCapacity())return!1;t=this.selectWeaponVersus(e,r,t,!1);return!(!t||(e.isBuilding()||r.isBuilding()?this.rangeHelper.tileDistance(e,r):this.rangeHelper.distance2(e,r)/Coords.LEPTONS_PER_TILE)>Math.max(t.range,e.sight))}scanForTarget(e,t,i,r,s,a=!1){let n={},o=Number.NEGATIVE_INFINITY;var l=this.getAvailableWeapons(e,!0,!1),t=r??(e.rules.guardRange||t.range)+1+SCAN_TARGET_FOUNDATION_ADJUST+i.rules.elevationModel.bonusCap+(t.projectileRules.isAntiAir?e.rules.airRangeBonus:0);for(const d of this.scanTechnosAround(e,t,i)){var h,c=this.selectWeaponFromList(e,d,d.tile,l,i,!1,!0,!0);c&&this.canPassiveAcquire(d,i)&&i.isValidTarget(d)&&(r?this.rangeHelper.isInRange(e,d,c.minRange,r,c.rules.cellRangefinding)&&(!s||this.rangeHelper.isInRange2(s,d,0,r)):this.rangeHelper.isInWeaponRange(e,d,c,i.rules))&&(a||this.losHelper.hasLineOfSight(e,d,c))&&(h=this.rangeHelper.distance3(e,d)/Coords.LEPTONS_PER_TILE,(h=this.computeThreat(d,e,c,h,i.rules.general.threat))>o&&(n={target:d,weapon:c},o=h))}return n.target&&e.rules.distributedFire&&this.updateDistributedFireHistory(n),n}scanTechnosAround(e,t,i){var r=e.getFoundation();const s=new Vector2(e.tile.rx,e.tile.ry),a=new Vector2(e.tile.rx+r.width-1,e.tile.ry+r.height-1);s.addScalar(-t),a.addScalar(t);t=new Box2(s,a);return i.map.technosByTile.queryRange(t)}canPassiveAcquire(e,t){return!e.owner.isNeutral&&!e.rules.civilian&&(!e.rules.insignificant||e.isBuilding()&&e.garrisonTrait?.isOccupied())&&(1<e.rules.threatPosed||e.isBuilding()&&e.garrisonTrait?.isOccupied()||0<e.rules.specialThreatValue&&!e.isBuilding()||e.rules.harvester||e.name===t.rules.general.paradrop.paradropPlane)}computeThreat(e,t,i,r,s){let a=[e.primaryWeapon,e.secondaryWeapon].filter(isNotNullOrUndefined).map(e=>e.warhead.rules.verses.get(t.rules.armor)??0).reduce((e,t)=>Math.max(e,t),0)*s.targetEffectivenessCoefficientDefault;return e.attackTrait?.currentTarget?.obj===t&&(a*=-1),a+=e.rules.specialThreatValue*s.targetSpecialThreatCoefficientDefault,a+=(i.warhead.rules.verses.get(e.rules.armor)??0)*s.myEffectivenessCoefficientDefault,a+=e.healthTrait.health/100*s.targetStrengthCoefficientDefault,a+=r*s.targetDistanceCoefficientDefault,a+=1e5,t.rules.vhpScan!==VhpScan.None&&(s=e.healthTrait.getProjectedHitPoints(),t.rules.vhpScan===VhpScan.Strong?s<=0&&(a=Number.NEGATIVE_INFINITY):t.rules.vhpScan===VhpScan.Normal&&(s<=0?a/=2:s<=e.healthTrait.maxHitPoints/2&&(a*=2))),t.rules.distributedFire&&(a-=1e6*(this.distributedFireHistory.get(e)??0)),a}updateDistributedFireHistory(e){if(50!==this.distributedFireHistory.get(e.target)){for(var[t,i]of this.distributedFireHistory)i--,i<=0?this.distributedFireHistory.delete(t):this.distributedFireHistory.set(t,i);this.distributedFireHistory.set(e.target,50)}}dispose(){this.distributedFireHistory.clear()}}const MAX_MOVE_ATTEMPTS=3,FACING_DELTA_NONHOMING_THRESH_DEG=11.25,FACING_DELTA_HOMING_THRESH_DEG=4*FACING_DELTA_NONHOMING_THRESH_DEG;class AttackTask extends Task{constructor(e,t,i,r={}){super(),this.game=e,this.target=t,this.weapon=i,this.options=r,this.moveExecuted=!1,this.moveAttempts=0,this.rangeCheckCooldown=0,this.lastInRangeTargetPosition=new Vector3_Vector3,this.lastInRangeSelfPosition=new Vector3_Vector3,this.initialIndirectTarget=!1,this.forceDropTarget=!1,this.rangeHelper=new RangeHelper(e.map.tileOccupation),this.losHelper=new LosHelper(e.map.tiles,e.map.tileOccupation),this.targetLinesConfig={pathNodes:[]},this.updateTargetLines(this.target,!0)}duplicate(){return new AttackTask(this.game,this.target,this.weapon,this.options)}getWeapon(){return this.weapon}setWeapon(e){this.weapon=e}setForceAttack(e){this.options.force=e}requestTargetUpdate(e){this.target.equals(e)||(this.needsTargetUpdate=e)}onTargetChange(e){let t=e.attackTrait,i=this.target;t.currentTarget=i,this.lastValidTargetPosition=i.obj?{tile:i.tile,onBridge:i.getBridge()}:void 0,this.initialTargetOwner=i.obj?.isTechno()?i.obj.owner:void 0,this.initialIndirectTarget=!i.obj&&this.game.map.tileOccupation.getObjectsOnTile(i.tile).some(e=>e.isOverlay()&&!e.isBridgePlaceholder()||e.isTerrain()),this.updateTargetLines(i,!0)}updateTargetLines(e,t){this.targetLinesConfig.target=e.obj,this.targetLinesConfig.pathNodes=e.obj?[]:[{tile:e.tile,onBridge:e.getBridge()}],this.targetLinesConfig.isAttack=t}onStart(t){if(!t.attackTrait)throw new Error(`Object ${t.name} has no attack trait`);if(0!==t.ammo){let e=this.game.map.tileOccupation;var i,r;t.attackTrait.attackState=AttackState.CheckRange,this.onTargetChange(t),this.initialSelfPosition={tile:t.tile,onBridge:t.isUnit()&&t.onBridge?e.getBridgeOnTile(t.tile):void 0},this.weapon.rules.limboLaunch&&t.isUnit()&&!this.target.obj&&(this.forceDropTarget=!0,{reachable:i,fallback:r}=this.findReachableMeleePosition(this.target.tile,!!this.target.getBridge(),{width:1,height:1},t),!i&&r&&(this.lastValidTargetPosition=r,this.updateTargetLines(this.game.createTarget(r.onBridge,r.tile),!1))),this.weapon.rules.limboLaunch&&this.target.obj?.isTechno()&&t.isUnit()&&!this.rangeHelper.isInWeaponRange(t,this.target.obj,this.weapon,this.game.rules)&&({reachable:i,fallback:r}=this.findReachableMeleePosition(this.target.obj.tile,this.target.obj.isUnit()&&this.target.obj.onBridge,this.target.obj.getFoundation(),t),i||(1<(t.unitOrderTrait.waypointPath?.waypoints?.length??0)?this.cancel():(this.forceDropTarget=!0,r&&(this.lastValidTargetPosition=r,this.updateTargetLines(this.game.createTarget(r.onBridge,r.tile),!1))))),this.rangeHelper.isInWeaponRange(t,this.target.obj??this.target.tile,this.weapon,this.game.rules)&&t.isUnit()&&t.rules.movementZone===MovementZone.Fly&&t.zone!==ZoneType.Air&&(t.rules.hoverAttack||t.isAircraft())&&this.children.push(new MoveTask(this.game,t.tile,!1).setCancellable(!1))}else this.cancel()}findReachableMeleePosition(r,e,t,s){let i=this.game.map,a=i.tileOccupation,n=e?a.getBridgeOnTile(r):void 0,o=new MovePositionHelper(i),l=s.rules.movementZone===MovementZone.Fly,h=(e,t)=>l||0<i.terrain.getPassableSpeed(e,s.rules.speedType,s.isInfantry(),!!t)&&o.isEligibleTile(e,t,n,r)&&!i.terrain.findObstacles({tile:e,onBridge:t},s).length,c,d=new RadialTileFinder(i.tiles,i.mapBounds,r,t,1,Math.ceil(this.weapon.rules.range),e=>{let t=!1;var i;return h(e,void 0)&&(c=c??{tile:e,onBridge:void 0},t=!0),void 0!==e.onBridgeLandType&&(i=a.getBridgeOnTile(e),h(e,i)&&(c=c??{tile:e,onBridge:i},t=!0)),!!t&&this.rangeHelper.isInWeaponRange(s,r,this.weapon,this.game.rules,e)});return{reachable:d.getNextTile(),fallback:c}}onEnd(e){e.isVehicle()&&e.turretTrait&&(e.turretTrait.desiredFacing=e.direction),e.attackTrait.attackState=AttackState.Idle,e.attackTrait.currentTarget=void 0;var t=this.game.rules.general.prism.type;e.isBuilding()&&e.name===t&&this.weapon.type!==WeaponType.Secondary&&this.countSupportBeamsAndFireDownTowers(e,t),this.weapon.rules.limboLaunch&&e.attackTrait.expirePassiveScanCooldown(),(e.isInfantry()||e.isVehicle())&&(e.isFiring=!1),this.weapon.hasBurstsLeft()&&this.weapon.resetBursts()}forceCancel(t){if(t.rules.movementZone!==MovementZone.Fly)return!1;if(!this.cancellable||this.children.some(e=>!e.cancellable))return!1;if(this.status===TaskStatus.Running||this.status===TaskStatus.Cancelling){if(this.children.filter(e=>e instanceof MoveTask).some(e=>!e.forceCancel(t)))return!1;this.onEnd(t),(t.isInfantry()||t.isVehicle())&&(t.isFiring=!1)}return this.status=TaskStatus.Cancelled,!0}onTick(r){let s=r.attackTrait;(r.isInfantry()||r.isVehicle())&&s.attackState!==AttackState.Firing&&(r.isFiring=!1);let t=this.target.obj,a=this.children.find(e=>e instanceof MoveInWeaponRangeTask);if(this.isCancelling()&&s.attackState!==AttackState.FireUp)return!r.airSpawnTrait?.isLaunchingMissiles()&&(a?.cancel(),!0);let n=!1;if(s.attackState===AttackState.FireUp){if(s.isDisabled())return!0;s.attackState=AttackState.Firing,n=!0}if(s.attackState===AttackState.Firing){if(this.initialIndirectTarget&&!this.game.map.getObjectsOnTile(this.target.tile).find(e=>e.isOverlay()&&!e.isBridgePlaceholder()||e.isTerrain()))return this.cancel(),this.onTick(r);if(n){var o=this.target.obj||this.target.tile;if(!this.game.isValidTarget(this.target.obj)||this.shouldDropTarget(this.target.obj)||!this.weapon.targeting.canTarget(this.target.obj,this.target.tile,this.game,!!this.options.force,!!this.options.passive)||!this.rangeHelper.isInWeaponRange(r,o,this.weapon,this.game.rules)||!this.losHelper.hasLineOfSight(r,o,this.weapon))return s.attackState=AttackState.CheckRange,this.onTick(r)}if(this.weapon.rules.limboLaunch){if((t?.isVehicle()||t?.isAircraft())&&t.parasiteableTrait?.isInfested())return!0;if(r.rules.movementZone!==MovementZone.Fly&&t?.isUnit()&&t.zone===ZoneType.Air)return!0}if(this.target.tile.onBridgeLandType&&r.tile.onBridgeLandType&&r.isUnit()&&(this.game.map.tileOccupation.getBridgeOnTile(this.target.tile)?.isHighBridge()||this.game.map.tileOccupation.getBridgeOnTile(r.tile)?.isHighBridge()))if((t?t.isUnit()&&(t.zone===ZoneType.Air||t.onBridge):this.target.isBridge())!==(r.zone===ZoneType.Air||r.onBridge))return!0;let e=1;o=this.game.rules.general.prism.type;if(r.isBuilding()&&r.name===o&&this.weapon.type!==WeaponType.Secondary&&(o=this.countSupportBeamsAndFireDownTowers(r,o),e=1+o*this.game.rules.general.prism.supportModifier),this.weapon.rules.spawner&&(r.isVehicle()||r.isAircraft())&&r.parasiteableTrait?.isParalyzed())return!0;if(0===r.ammo)return r.isAircraft()&&(r.rules.fighter||r.rules.spawned)&&a?.cancel(),!0;let i=!1;if(this.weapon.rules.limboLaunch){let t=a;if(!t){let e=r.unitOrderTrait.getCurrentTask();if(e&&e!==this&&s.getOpportunityFireTask()===this){if(!(e instanceof MoveTask))return e.cancel(),!1;t=e}}if(t){if(!t.forceCancel(r))return!1;r.moveTrait.lastTargetOffset=void 0,r.moveTrait.lastVelocity=void 0}i=!0}return(this.weapon.fire(this.target,this.game,e),i)?!0:!!this.weapon.rules.fireOnce||(!(!this.options.passive||!r.rules.distributedFire)||(s.attackState=AttackState.JustFired,!1))}if(s.attackState===AttackState.JustFired)return s.attackState=AttackState.PrepareToFire,this.onTick(r);this.needsTargetUpdate&&(this.target=this.needsTargetUpdate,t=this.target.obj,this.needsTargetUpdate=void 0,this.onTargetChange(r),t||a?.retarget(this.target.tile,!!this.target.getBridge())),t?.isTechno()&&t.replacedBy&&(l=this.game.createTarget(t.replacedBy,t.replacedBy.tile),this.target=l,t=t.replacedBy,this.onTargetChange(r));let i=this.game.isValidTarget(t)&&!this.shouldDropTarget(t);if(i){let e=this.weapon.targeting.canTarget(t,this.target.tile,this.game,!!this.options.force,!!this.options.passive);if(!e||!r.armedTrait.isEquippedWithWeapon(this.weapon)){var l=s.selectWeaponVersus(r,this.target,this.game,this.options.force,this.options.passive);if(l){if(this.setWeapon(l),s.attackState!==AttackState.CheckRange)return s.attackState=AttackState.CheckRange,this.onTick(r);e=!0}else e=!1}i=e}if(i&&(h=this.lastTargetTpCheck,t?.isUnit()&&h&&t.moveTrait.lastTeleportTick>=h?(i=!1,this.rangeCheckCooldown=0):this.lastTargetTpCheck=this.game.currentTick),i&&t&&(this.lastValidTargetPosition={tile:t.tile,onBridge:this.target.getBridge()}),i||(this.targetLinesConfig.isAttack=!1),s.attackState===AttackState.CheckRange){if(0<this.rangeCheckCooldown)return this.rangeCheckCooldown--,!1;let e=this.target.obj?i?this.target.obj:this.lastValidTargetPosition.tile:this.target.tile;var h=this.target.obj?i?this.target.obj.isBuilding()?this.target.obj.centerTile:this.target.obj.tile:this.lastValidTargetPosition.tile:this.target.tile;if(!this.rangeHelper.isInWeaponRange(r,e,this.weapon,this.game.rules)||!this.losHelper.hasLineOfSight(r,e,this.weapon)||r.isUnit()&&r.rules.balloonHover&&!r.rules.hoverAttack&&!a&&r.tile!==h&&!this.options.holdGround||r.isAircraft()&&this.weapon.projectileRules.iniRot<=1&&!a){if(r.isUnit()&&!this.options.holdGround&&this.game.map.isWithinBounds(h)){if(a){if(a.target!==this.target.obj||i)if(i&&this.target.obj&&this.rangeHelper.tileDistance(this.target.obj,this.lastSelfMoveTargetTile)>this.weapon.range)a.retarget(this.target.obj,!!this.target.getBridge()),this.lastSelfTileBeforeMove=r.tile,this.lastSelfMoveTargetTile=this.target.obj?.tile??this.target.tile;else{if(void 0!==this.options.leashTiles&&this.rangeHelper.tileDistance(this.initialSelfPosition.tile,r.tile)>this.options.leashTiles)return a.cancel(),!0;var c=e instanceof GameObject&&e.isUnit()?e.moveTrait.baseSpeed:0,d=Math.ceil((this.rangeHelper.tileDistance(r,e)-(this.weapon.range+1))/((r.moveTrait.baseSpeed+c)/Coords.LEPTONS_PER_TILE));0<d&&(this.rangeCheckCooldown=Math.min(GameSpeed.BASE_TICKS_PER_SECOND,d))}else{let e;e=void 0!==this.options.leashTiles?this.game.createTarget(this.initialSelfPosition.onBridge,this.initialSelfPosition.tile):this.game.createTarget(this.lastValidTargetPosition.onBridge,this.lastValidTargetPosition.tile),s.currentTarget=e,a.retarget(e.tile,e.isBridge()),this.updateTargetLines(e,!1)}return!1}if(!r.moveTrait||r.moveTrait.isDisabled())return!0;if(this.isCancelling())return!0;if(r.tile===this.lastSelfTileBeforeMove||this.moveExecuted&&r.moveTrait.lastMoveResult===MoveResult.Fail?this.moveAttempts++:this.moveAttempts=0,this.weapon.rules.limboLaunch&&r.defaultToGuardArea&&t&&this.moveExecuted&&r.moveTrait.lastMoveResult===MoveResult.Fail&&this.rangeHelper.isInRange(r,t,0,r.armedTrait.computeGuardScanRange(this.weapon),!0))return!0;if(this.moveAttempts>MAX_MOVE_ATTEMPTS)return!0;0<this.moveAttempts&&this.children.push(new WaitMinutesTask(1/60));c=e,d=t&&!i?this.lastValidTargetPosition.onBridge:this.target.getBridge();return a=new MoveInWeaponRangeTask(this.game,c,!!d,this.weapon),a.blocking=!1,this.children.push(a),this.moveExecuted=!0,this.lastSelfTileBeforeMove=r.tile,this.lastSelfMoveTargetTile=c instanceof GameObject?c.tile:c,this.onTick(r)}return!0}if(this.moveExecuted=!1,this.moveAttempts=0,a&&(r.rules.balloonHover&&!r.rules.hoverAttack||r.rules.fighter||r.rules.spawned||r.rules.movementZone===MovementZone.Fly&&!this.rangeHelper.isInRange2(r,this.target.obj??this.target.tile,this.weapon.minRange,this.weapon.range-1)||a.cancel()),a&&(r.isInfantry()||this.weapon.rules.spawner))return!1;if(a?.children.some(e=>!e.cancellable)&&this.weapon.rules.limboLaunch)return!1;if(a&&a.shouldAirStrafe(r)&&this.target.obj?.isUnit()&&this.target.obj.moveTrait.isMoving()&&1<this.weapon.range&&!this.rangeHelper.isInRange2(r,this.target.obj,this.weapon.minRange,this.weapon.range-1))return!1;s.attackState=AttackState.PrepareToFire}if(s.attackState!==AttackState.PrepareToFire)return!1;if(!i||s.isDisabled())return a?.cancel(),!0;d=this.target.getWorldCoords(),c=r.position.worldPosition;if(!(this.lastInRangeTargetPosition.length()&&this.lastInRangeTargetPosition.equals(d)&&this.lastInRangeSelfPosition.length()&&this.lastInRangeSelfPosition.equals(c)))return this.lastInRangeTargetPosition.copy(d),this.lastInRangeSelfPosition.copy(c),s.attackState=AttackState.CheckRange,this.onTick(r);if(!(this.weapon.rules.omniFire||r.rules.omniFire&&r.rules.fighter)){var c=(new Vector3_Vector3).copy(d).sub(c),e=FacingUtil.fromMapCoords(new Vector2(c.x,c.z)),c=this.weapon.projectileRules.rot?FACING_DELTA_HOMING_THRESH_DEG:FACING_DELTA_NONHOMING_THRESH_DEG;if((r.isVehicle()||r.isBuilding())&&r.turretTrait){if(r.turretTrait.desiredFacing=e,Math.abs(e-r.turretTrait.facing)>=c)return!1}else if(Math.abs(e-r.direction)>=c){if(r.isAircraft())return r.direction=FacingUtil.tick(r.direction,e,r.rules.rot).facing,!1;if(a)return!1;if(this.options.disallowTurning)return!0;if(r.isVehicle())return this.children.push(new TurnTask(e)),!1;r.direction=e}}if(!this.losHelper.hasLineOfSight(r,this.target.obj||this.target.tile,this.weapon))return s.attackState=AttackState.CheckRange,this.onTick(r);if(s.isOnCooldown(r))return!1;if(this.weapon.warhead.rules.temporal&&r.temporalTrait.getTarget()===this.target.obj)return!1;if(this.weapon.rules.suicide&&this.weapon.type!==WeaponType.DeathWeapon)return this.game.destroyObject(r,{player:r.owner,obj:r,weapon:this.weapon}),!0;e=this.game.rules.general.prism.type;return r.isBuilding()&&r.name===e&&this.weapon.type!==WeaponType.Secondary&&this.fireUpPrismSupportTowers(r,e),(r.isInfantry()||r.isVehicle())&&(r.isFiring=!0),r.art.fireUp?(r.isInfantry()&&r.suppressionTrait?.isSuppressed()||this.children.push(new WaitTicksTask(r.art.fireUp).setCancellable(!1)),s.attackState=AttackState.FireUp,!1):(s.attackState=AttackState.Firing,this.onTick(r))}shouldDropTarget(e){return this.forceDropTarget||e?.isTechno()&&(this.weapon.rules.limboLaunch&&((e.isVehicle()||e.isAircraft())&&e.parasiteableTrait?.isInfested()||e.invulnerableTrait.isActive())||e.warpedOutTrait.isInvulnerable()&&!this.weapon.warhead.rules.temporal||this.initialTargetOwner!==e.owner)}fireUpPrismSupportTowers(t,i){var e;for(e of t.owner.getOwnedObjectsByType(ObjectType.Building).filter(e=>e.name===i&&e.secondaryWeapon&&!e.unitOrderTrait.hasTasks()&&e.attackTrait&&!e.attackTrait.isDisabled()&&!e.attackTrait.isOnCooldown(e)).filter(e=>this.rangeHelper.isInWeaponRange(e,t,e.secondaryWeapon,this.game.rules)).slice(0,this.game.rules.general.prism.supportMax))e.unitOrderTrait.addTask(e.attackTrait.createAttackTask(this.game,t,t.centerTile,e.secondaryWeapon,{passive:!0}))}countSupportBeamsAndFireDownTowers(t,i){var e,r=t.owner.getOwnedObjectsByType(ObjectType.Building).filter(e=>e.name===i&&e.attackTrait?.currentTarget?.obj===t);for(e of r)e.unitOrderTrait.getCurrentTask()?.cancel();return Math.min(this.game.rules.general.prism.supportMax,r.length)}getTargetLinesConfig(){return this.targetLinesConfig}}class AttackMoveTargetTask extends AttackTask{constructor(e,t,i){if(super(e,t,i),this.isAttackMove=!0,this.attackPerformed=!1,this.passedFirstWaypoint=!1,this.internalTargetUpdateRequested=!1,this.scanCooldownTicks=0,!t.obj?.isTechno())throw new Error("Target must be a techno object");this.initialTarget=t,this.initialWeapon=i,this.requestedTarget=t}duplicate(){return new AttackMoveTargetTask(this.game,this.initialTarget,this.initialWeapon)}requestTargetUpdate(e){this.internalTargetUpdateRequested?(this.requestedTarget=e,this.internalTargetUpdateRequested=!1):(this.requestedTarget===this.initialTarget?this.requestedTarget=e:this.attackPerformed=!0,this.initialTarget=e),super.requestTargetUpdate(e)}onTargetChange(e){super.onTargetChange(e);e=e.attackTrait.currentTarget;e&&e.obj!==this.initialTarget.obj&&e.obj!==this.requestedTarget.obj&&(this.requestedTarget===this.initialTarget&&(this.requestedTarget=e),this.initialTarget=e)}onTick(t){if(t.moveTrait.moveState===MoveState.Moving&&(this.passedFirstWaypoint=!0),this.scanCooldownTicks=Math.max(0,this.scanCooldownTicks-1),t.attackTrait&&!t.attackTrait.isDisabled()&&!this.isCancelling()&&(this.requestedTarget===this.initialTarget||this.attackPerformed)){if(!(t.moveTrait.isIdle()||t.tile===this.lastScanTile&&this.scanCooldownTicks)){this.lastScanTile=t.tile,this.scanCooldownTicks=this.game.rules.general.normalTargetingDelay;let e=t.attackTrait.selectDefaultWeapon(t);if(e&&(this.passedFirstWaypoint||!e.getCooldownTicks())){var i=t.attackTrait.scanForTarget(t,e,this.game);if(i.target){let{target:e,weapon:t}=i;if(!t.getCooldownTicks()){this.options.holdGround=!0,this.options.passive=!0,this.setWeapon(t);var r=this.game.createTarget(e,e.tile);return this.internalTargetUpdateRequested=!0,this.requestTargetUpdate(r),this.attackPerformed=!1}}}}if(this.attackPerformed){if(!t.isSpawned){if(!this.forceCancel(t))throw new Error("Force cancel failed");return!0}this.attackPerformed=!1,this.passedFirstWaypoint=!1,this.options.holdGround=!1,this.options.passive=!1,this.setWeapon(this.initialWeapon),this.internalTargetUpdateRequested=!0,this.requestTargetUpdate(this.initialTarget)}}r=super.onTick(t);return r&&this.requestedTarget!==this.initialTarget?(this.attackPerformed=!0,this.isCancelling()||t.attackTrait.isDisabled()):r}}class AttackMoveTask extends MoveTask{constructor(){super(...arguments),this.isAttackMove=!0,this.attackPerformed=!1,this.passedFirstWaypoint=!1}duplicate(){return new AttackMoveTask(this.game,this.targetTile,this.toBridge,this.options)}onTick(i){if(i.moveTrait.moveState===MoveState.Moving&&(this.passedFirstWaypoint=!0),i.moveTrait.moveState===MoveState.ReachedNextWaypoint&&i.attackTrait&&!i.attackTrait.isDisabled()&&(i.rules.movementZone!==MovementZone.Fly||!i.rules.balloonHover)&&(!i.ammoTrait||i.ammoTrait.ammo||!i.rules.manualReload)&&!this.isCancelling()){let e=i.attackTrait.selectDefaultWeapon(i);if(e&&(this.passedFirstWaypoint||e&&!e.getCooldownTicks())){var r=i.attackTrait.scanForTarget(i,e,this.game);if(r.target){let{target:e,weapon:t}=r;if(!t.getCooldownTicks()){r=i.attackTrait.createAttackTask(this.game,e,e.tile,t,{holdGround:!0,passive:!0});return this.children.push(r),this.useChildTargetLines=!0,this.attackPerformed=!0,i.moveTrait.velocity.set(0,0,0),i.moveTrait.currentWaypoint=void 0,i.moveTrait.collisionState=CollisionState.Waiting,!1}}}if(this.attackPerformed){if(!i.isSpawned){if(!this.forceCancel(i))throw new Error("Force cancel failed");return!0}this.attackPerformed=!1,this.passedFirstWaypoint=!1,this.useChildTargetLines=!1,i.moveTrait.collisionState=CollisionState.Resolved,this.updateTarget(this.targetTile,this.toBridge)}}return super.onTick(i)}}class ExitFactoryTask extends MoveTask{constructor(e,t,i,r){super(e,i,!1,{ignoredBlockers:[t],closeEnoughTiles:0,strictCloseEnough:!0,forceWaitOnPathBlocked:t.factoryTrait?.type!==FactoryType.InfantryType}),this.factory=t,this.rallyPoint=r,this.preventOpportunityFire=!0,this.rampBlockersPushed=!1,this.cancellable=!1}onStart(t){super.onStart(t),this.factory.factoryTrait?.type===FactoryType.UnitType&&(this.checkRampTiles=this.game.map.tileOccupation.calculateTilesForGameObject(this.factory.tile,this.factory).filter(e=>0<this.game.map.terrain.getPassableSpeed(e,t.rules.speedType,t.isInfantry(),!1)))}canStopAtTile(e,t,i){return!this.game.map.tileOccupation.isTileOccupiedBy(t,this.factory)&&super.canStopAtTile(e,t,i)}onTick(e){if(this.checkRampTiles){for(var t of this.checkRampTiles){var i,r;for(i of this.game.map.tileOccupation.getGroundObjectsOnTile(t))if(i.isUnit()){if(this.rampBlockersPushed)return!1;let e=new ScatterTask(this.game,void 0,{excludedTiles:this.checkRampTiles});e.setCancellable(!1);let t=i.unitOrderTrait.getCurrentTask();t?t.constructor!==MoveTask&&t.constructor!==AttackTask&&t.constructor!==AttackMoveTask&&t.constructor!==AttackMoveTargetTask||(r=t.duplicate(),t.cancel(),i.unitOrderTrait.addTaskNext(r),i.unitOrderTrait.addTaskNext(e)):i.unitOrderTrait.addTask(e)}}if(!this.rampBlockersPushed)return!(this.rampBlockersPushed=!0);this.checkRampTiles=void 0}return e.moveTrait.moveState===MoveState.ReachedNextWaypoint&&this.options?.ignoredBlockers&&!this.game.map.terrain.isBlockerObject(this.factory,e.tile,!1,e.rules.speedType,e.isInfantry())&&(this.options.ignoredBlockers=void 0,this.preventOpportunityFire=!1,this.rallyPoint&&(this.updateTarget(this.rallyPoint.tile,!!this.rallyPoint.onBridge),this.cancellable=!0,this.options.closeEnoughTiles=this.game.rules.general.closeEnough,this.options.strictCloseEnough=!1,this.options.forceWaitOnPathBlocked=!1)),super.onTick(e)}}class CardinalTileFinder{constructor(e,t,i,r,s,a=()=>!0){this.tiles=e,this.mapBounds=t,this.startTile=i,this.maxDistance=s,this.predicate=a,this.dirVec=new Vector2(10,0),this.finished=!1,this.diagonal=!0,this.distance=r}getNextTile(){if(!this.finished){let t;do{let e={x:this.startTile.rx,y:this.startTile.ry};e.x+=this.distance*Math.sign(this.dirVec.x),e.y+=this.distance*Math.sign(this.dirVec.y),this.dirVec.rotateAround(new Vector2,Math.PI/4*(this.diagonal?1:2)).round();var i=this.tiles.getByMapCoords(e.x,e.y);if(i&&this.mapBounds.isWithinBounds(i)&&this.predicate(i)&&(t=i),!this.dirVec.angle()){if(this.maxDistance&&this.distance>=this.maxDistance)return this.finished=!0,t;this.distance++}}while(!t);return t}}}(NotifySell=NotifySell||{}).onSell=Symbol();class DockableTrait{[NotifyUnspawn.onUnspawn](e){this.undock(e),this.reservedDock?.dockTrait.unreserveDockForUnit(e)}[NotifyOwnerChange.onChange](e){e.owner!==this.dock?.owner&&this.undock(e),e.owner!==this.reservedDock?.owner&&this.reservedDock?.dockTrait.unreserveDockForUnit(e)}[NotifyTeleport.onBeforeTeleport](e,t,i,r){r||(this.undock(e),this.reservedDock?.dockTrait.unreserveDockForUnit(e))}undock(e){this.dock&&!this.dock.isDisposed&&this.dock.dockTrait.undockUnit(e)}dispose(){this.dock=void 0,this.reservedDock=void 0}}class DockTrait{constructor(e,t,i,r){this.building=e,this.tiles=t,this.numberOfDocks=i,this.dockingOffsets=r,this.ticksWhenWarpedOut=!0,this.unitsByDockNumber=new Array(i).fill(void 0),this.reservedDocks=new Array(i).fill(void 0)}[NotifySpawn.onSpawn](){this.dockTiles=[];for(let e=0;e<this.numberOfDocks;e++){var t=this.findDockTile(e);if(!t)throw new Error(`Docking tile ${e} not found for object "${this.building.name}"`);this.dockTiles[e]=t}}[NotifyUnspawn.onUnspawn](){for(let e=0;e<this.numberOfDocks;e++)this.unreserveDockAt(e)}[NotifyTick_NotifyTick.onTick](){for(let e=0;e<this.numberOfDocks;e++){var t=this.unitsByDockNumber[e];t&&t.tile!==this.getDockTile(e)&&this.undockUnit(t)}}[NotifyDestroy.onDestroy](e,t,i,r){var s=(e.rules.unitRepair||e.helipadTrait)&&!e.rules.naval&&!i?.weapon?.warhead.rules.temporal;if(s)for(var a of this.unitsByDockNumber)a&&!a.isDestroyed&&(s?t.destroyObject(a,i,r):this.undockUnit(a))}[NotifySell.onSell](r,s){if(r.helipadTrait&&this.hasDockedUnits()){var a,e,n;let t=[],i=0;for(a of[...r.owner.buildings].filter(e=>e.helipadTrait&&(e.dockTrait?.getAvailableDockCount()??!1)&&e!==r)){let e=a.dockTrait?.getAvailableDockCount()??0;for(;0<e&&i<this.unitsByDockNumber.length;)t.push(a),e--,i++;if(i===this.unitsByDockNumber.length)break}i=0;for(e of this.unitsByDockNumber)e&&((n=t[i])?e.unitOrderTrait.addTask(new MoveToDockTask(s,n)):e.unitOrderTrait.addTask(new TaskGroup(new MoveTask(s,e.tile,!1),new CallbackTask(e=>{e.crashableTrait?e.crashableTrait.crash({player:r.owner}):s.destroyObject(e,{player:r.owner})})).setCancellable(!1))),i++}else{var t,i=r.rules.unitRepair&&!r.rules.naval;for(t of this.unitsByDockNumber)t&&(i?s.sellTrait.sell(t):this.undockUnit(t))}}[NotifyOwnerChange.onChange](e,t,i){for(var r of this.unitsByDockNumber)r&&i.changeObjectOwner(r,e.owner)}getFirstAvailableDockNumber(){if(!this.building?.warpedOutTrait.isActive()){var e=this.unitsByDockNumber.findIndex((e,t)=>!e&&!this.reservedDocks[t]);if(-1!==e)return e}}getAvailableDockCount(){return this.building?.warpedOutTrait.isActive()?0:this.unitsByDockNumber.filter((e,t)=>!e&&!this.reservedDocks[t]).length}getFirstEmptyDockNumber(){if(!this.building?.warpedOutTrait.isActive()){var e=this.unitsByDockNumber.findIndex(e=>!e);if(-1!==e)return e}}getDockOffset(e){if(e>this.numberOfDocks-1)throw new RangeError(`Index ${e} exceeds available docks (${this.numberOfDocks})`);return this.dockingOffsets[e]}getDockTile(e){if(e>this.numberOfDocks-1)throw new RangeError(`Index ${e} exceeds available docks (${this.numberOfDocks})`);return this.dockTiles[e]}getDockNumberByTile(e){e=this.dockTiles.indexOf(e);if(-1!==e)return e}getAllDockTiles(){return[...this.dockTiles]}findDockTile(e){if(e>this.numberOfDocks-1)throw new RangeError(`Index ${e} exceeds available docks (${this.numberOfDocks})`);var t=this.building.position.getMapPosition(),e=this.getDockOffset(e);return this.tiles.getByMapCoords(Math.floor((t.x+e.x)/Coords.LEPTONS_PER_TILE),Math.floor((t.y+e.z)/Coords.LEPTONS_PER_TILE))}isValidUnitForDock(e){return(this.building.unitRepairTrait&&e.isVehicle()&&!this.building.helipadTrait&&(!e.rules.consideredAircraft||e.rules.landable)||e.rules.dock.includes(this.building.name)&&!(e.isAircraft()&&!this.building.helipadTrait))&&this.building.rules.naval===e.rules.naval}dockUnitAt(e,t){if(t>this.numberOfDocks-1)throw new RangeError(`Index ${t} exceeds available docks (${this.numberOfDocks})`);if(this.unitsByDockNumber[t])throw new Error("Another unit is already docked at dock #"+t);let i=e.traits.find(DockableTrait);if(!i)throw new Error(`Unit "${e.name}" cannot be docked to `+this.building.name);this.unitsByDockNumber[t]=e,i.dock=this.building}undockUnitAt(e){if(e>this.numberOfDocks-1)throw new RangeError(`Index ${e} exceeds available docks (${this.numberOfDocks})`);let t=this.unitsByDockNumber[e];t&&(this.unitsByDockNumber[e]=void 0,t.traits.get(DockableTrait).dock=void 0)}undockUnit(e){e=this.unitsByDockNumber.indexOf(e);-1!==e&&this.undockUnitAt(e)}isDocked(e){return this.unitsByDockNumber.includes(e)}hasDockedUnits(){return!!this.unitsByDockNumber.find(e=>e)}getDockedUnits(){return this.unitsByDockNumber.filter(isNotNullOrUndefined)}reserveDockAt(e,t){if(t>this.numberOfDocks-1)throw new RangeError(`Index ${t} exceeds available docks (${this.numberOfDocks})`);if(this.reservedDocks[t])throw new Error(`Dock #${t} is already reserved by `+this.reservedDocks[t].name);(this.reservedDocks[t]=e).traits.get(DockableTrait).reservedDock?.dockTrait.unreserveDockForUnit(e),e.traits.get(DockableTrait).reservedDock=this.building}unreserveDockAt(e){if(e>this.numberOfDocks-1)throw new RangeError(`Index ${e} exceeds available docks (${this.numberOfDocks})`);let t=this.reservedDocks[e];t&&(this.reservedDocks[e]=void 0,t.traits.get(DockableTrait).reservedDock=void 0)}unreserveDockForUnit(e){e=this.reservedDocks.indexOf(e);-1!==e&&this.unreserveDockAt(e)}hasReservedDockForUnit(e){return!!this.reservedDocks.includes(e)}hasReservedDockAt(e){return!!this.reservedDocks[e]}getReservedDockForUnit(e){e=this.reservedDocks.indexOf(e);if(-1!==e)return e}dispose(){this.building=void 0}}class FactoryProduceUnitEvent{constructor(e){this.target=e,this.type=EventType.FactoryProduceUnit}}!function(e){e[e.All=0]="All",e[e.Ground=1]="Ground",e[e.Air=2]="Air"}(LayerType=LayerType||{});class TileOccupation{get onChange(){return this._onChange.asEvent()}constructor(e){this.tiles=e,this.tileOccupation=[],this.emptyTiles=new Set,this._onChange=new EventDispatcher;let t=this.tileOccupation;for(var i of e.getAll())t[i.rx]=t[i.rx]||[],t[i.rx][i.ry]=new Set,this.emptyTiles.add(i)}occupyTileRange(e,t){let i=this.calculateTilesForGameObject(e,t);i.forEach(e=>this.occupyTile(e,t)),this._onChange.dispatch(this,{tiles:i,object:t,type:"added"})}unoccupyTileRange(e,t){let i=this.calculateTilesForGameObject(e,t);i.forEach(e=>this.unoccupyTile(e,t)),this._onChange.dispatch(this,{tiles:i,object:t,type:"removed"})}occupySingleTile(e,t){this.occupyTile(e,t),this._onChange.dispatch(this,{tiles:[e],object:t,type:"added"})}unoccupySingleTile(e,t){this.unoccupyTile(e,t),this._onChange.dispatch(this,{tiles:[e],object:t,type:"removed"})}calculateTilesForGameObject(e,t){return this.tiles.getInRectangle(e,t.getFoundation())}occupyTile(e,t){let i=this.tileOccupation[e.rx]?.[e.ry];i&&(i.add(t),this.emptyTiles.delete(e),e.landType=this.computeTileLandType(e),e.onBridgeLandType=this.computeOnBridgeLandType(e))}unoccupyTile(e,t){let i=this.tileOccupation[e.rx]?.[e.ry];i&&(i.delete(t),i.size||this.emptyTiles.add(e),e.landType=this.computeTileLandType(e),e.onBridgeLandType=this.computeOnBridgeLandType(e))}isTileOccupiedBy(e,t){return!!this.tileOccupation[e.rx]?.[e.ry]?.has(t)}computeTileLandType(e){if(e.landType===LandType.Rock)return LandType.Rock;var t,i=getLandType(e.terrainType);for(t of this.tileOccupation[e.rx]?.[e.ry]??[]){if(t.isBuilding()&&t.rules.wall)return LandType.Wall;if(t.isOverlay()&&!t.isBridge()&&!t.isBridgePlaceholder())if(t.getLandType()!==LandType.Clear)return t.getLandType()}return i}computeOnBridgeLandType(e){for(var t of this.tileOccupation[e.rx]?.[e.ry]??[])if(t.isOverlay()&&t.isBridge())return t.getLandType()}getTileZone(e,t=!1){return getZoneType(t?e.landType:e.onBridgeLandType??e.landType)}getBridgeOnTile(e){for(var t of this.tileOccupation[e.rx]?.[e.ry]??[])if(t.isOverlay()&&t.isBridge())return t}getObjectsOnTile(e){return[...this.tileOccupation[e.rx]?.[e.ry]??[]]}getGroundObjectsOnTile(e){let t=[];for(var i of this.tileOccupation[e.rx]?.[e.ry]??[])i.isTechno()&&!i.isBuilding()&&i.zone===ZoneType.Air||t.push(i);return t}getAirObjectsOnTile(e){let t=[];for(var i of this.tileOccupation[e.rx]?.[e.ry]??[])i.isUnit()&&i.zone===ZoneType.Air&&t.push(i);return t}getObjectsOnTileByLayer(e,t){if(t===LayerType.Ground)return this.getGroundObjectsOnTile(e);if(t===LayerType.Air)return this.getAirObjectsOnTile(e);if(t===LayerType.All)return this.getObjectsOnTile(e);throw new Error(`Unhandled layer type "${t}"`)}getEmptyTiles(){return[...this.emptyTiles]}}(NotifyWarpChange_NotifyWarpChange=NotifyWarpChange_NotifyWarpChange||{}).onChange=Symbol(),(NotifyProduceUnit=NotifyProduceUnit||{}).onProduce=Symbol(),function(e){e[e.Idle=0]="Idle",e[e.Delivering=1]="Delivering"}(FactoryStatus=FactoryStatus||{});class FactoryTrait{constructor(e,t=!1){this.type=e,this.isCloningVats=t,this.status=FactoryStatus.Idle}[NotifySpawn.onSpawn](e,t){this.resetRallyPoint(e,t)}resetRallyPoint(e,t){var i;[FactoryType.BuildingType,FactoryType.AircraftType].includes(this.type)||(i=this.computeDefaultRallyPoint(e,this.type,t.map),e.rallyTrait?.changeRallyPoint(i,e,t))}[NotifyWarpChange_NotifyWarpChange.onChange](t,e,i){if(t.owner.production){let e=[];e=this.type===FactoryType.BuildingType?[QueueType.Structures,QueueType.Armory]:[t.owner.production.getQueueTypeForFactory(this.type)];for(var r of e)t.owner.production.getQueue(r).notifyUpdated()}}[NotifyOwnerChange.onChange](e,t,i){this.status===FactoryStatus.Delivering&&e.rules.deployTime&&this.deliveringUnit&&!this.deliveringUnit.isDestroyed&&this.unitIsInsideFactory(this.deliveringUnit,e,i)&&i.changeObjectOwner(this.deliveringUnit,e.owner)}[NotifyDestroy.onDestroy](e,t,i,r){this.status===FactoryStatus.Delivering&&e.rules.deployTime&&this.deliveringUnit&&!this.deliveringUnit.isDestroyed&&e.deathType!==DeathType.Temporal&&this.unitIsInsideFactory(this.deliveringUnit,e,t)&&t.destroyObject(this.deliveringUnit,i,r)}[NotifyTick_NotifyTick.onTick](i,r){if(this.status===FactoryStatus.Delivering){if(!this.deliveringUnit||this.deliveringUnit.isDestroyed){if(this.buildingProductionTicks=this.buildingProductionTicks??1,0<this.buildingProductionTicks--)return;this.buildingProductionTicks=void 0}else if(!this.unitHasClearedFactory(this.deliveringUnit,i,r))return;return this.status=FactoryStatus.Idle,void(this.deliveringUnit=void 0)}if(i.owner.production&&!i.warpedOutTrait.isActive()){let e=i.owner.production.getPrimaryFactory(this.type);if((e?.warpedOutTrait.isActive()||e===i||e?.factoryTrait?.deliveringUnit&&e.factoryTrait.type===FactoryType.UnitType)&&this.type!==FactoryType.BuildingType){let e=i.owner.production.getQueueForFactory(this.type);if(e&&e.status===QueueStatus.Ready){let t=e.getFirst();if(this.type===FactoryType.AircraftType){let e=this.produceAircraftAt(i,t,r);var s;if(!e)for(s of[...i.owner.buildings].filter(e=>e.factoryTrait?.type===FactoryType.AircraftType&&e.helipadTrait)){if(e)break;e=this.produceAircraftAt(s,t,r)}if(!e)return}else{var a;if(this.produceGroundUnitAt(i,t,r),!this.isCloningVats&&this.type===FactoryType.InfantryType)for(a of[...i.owner.buildings].filter(e=>e.factoryTrait&&e.rules.cloning))a.factoryTrait.status===FactoryStatus.Idle&&a.factoryTrait.produceGroundUnitAt(a,t,r)}i.owner.addUnitsBuilt(t.rules,1),t.creditsSpent=0,t.progress=0,e.shift(t.rules,1),e.currentSize&&(e.status=QueueStatus.Active)}}}}unitIsInsideFactory(e,t,i){return i.map.tileOccupation.isTileOccupiedBy(e.tile,t)&&e.zone!==ZoneType.Air}unitHasClearedFactory(e,t,i){return!i.map.tileOccupation.isTileOccupiedBy(e.tile,t)||e.rules.consideredAircraft&&e.position.tileElevation>=t.art.height}produceGroundUnitAt(t,e,i){let r=i.createUnitForPlayer(e.rules,t.owner);e.rules.trainable&&t.owner.canProduceVeteran(r.rules)&&r.veteranTrait?.setVeteranLevel(VeteranLevel.Veteran),r.isInfantry()&&(r.position.subCell=Infantry_Infantry.SUB_CELLS[0]);let s=this.computeInternalRallyPoint(t,this.type,t.rallyTrait.getRallyPoint(),i.map);this.type!==FactoryType.UnitType&&(s=t.rallyTrait.findRallyPointforUnit(r,s,i.map,!1,t.tile.z));let a;a=this.type===FactoryType.NavalUnitType?s:(e=this.computeExitCoords(t,this.type),i.map.tiles.getByMapCoords(Math.floor(e.rx),Math.floor(e.ry))),r.rules.consideredAircraft&&(s=a);let n;if(t.rallyTrait.getRallyPoint()!==s&&(n=t.rallyTrait.findRallyNodeForUnit(r,i.map)),r.isInfantry()){let t=i.map.tileOccupation.getObjectsOnTileByLayer(n?.tile??s,r.rules.consideredAircraft?LayerType.Air:LayerType.Ground).filter(e=>e.isInfantry()&&e.moveTrait.moveState!==MoveState.Moving).map(e=>e.position.subCell);r.position.subCell=Infantry_Infantry.SUB_CELLS.find(e=>!t.includes(e))??Infantry_Infantry.SUB_CELLS[0]}function o(){var e;r.rules.consideredAircraft?(e=n??{tile:s,onBridge:void 0},r.unitOrderTrait.addTaskNext(new MoveTask(i,e.tile,!!e.onBridge,{closeEnoughTiles:i.rules.general.closeEnough}))):r.unitOrderTrait.addTaskNext(new ExitFactoryTask(i,t,s,n))}r.direction=270,i.spawnObject(r,a),i.traits.filter(NotifyProduceUnit).forEach(e=>{e[NotifyProduceUnit.onProduce](r,i)}),i.events.dispatch(new FactoryProduceUnitEvent(r)),t.rules.deployTime?r.unitOrderTrait.addTask(new TaskGroup(new WaitMinutesTask(t.rules.deployTime),new CallbackTask(()=>{t.isSpawned&&t.buildStatus!==BuildStatus.BuildDown&&o()})).setCancellable(!1)):o(),this.status=FactoryStatus.Delivering,this.deliveringUnit=r}produceAircraftAt(e,t,i){let r=e.traits.find(DockTrait);if(!r)return!1;var s=r.getFirstAvailableDockNumber();if(void 0===s)return!1;let a=i.createUnitForPlayer(t.rules,e.owner);t.rules.trainable&&e.owner.canProduceVeteran(a.rules)&&a.veteranTrait?.setVeteranLevel(VeteranLevel.Veteran);t=r.getDockOffset(s);return a.position.moveToLeptons(e.position.getMapPosition()),a.position.moveByLeptons3(t),i.spawnObject(a,a.position.tile),r.dockUnitAt(a,s),a.isAircraft()&&a.airportBoundTrait&&(a.airportBoundTrait.preferredAirport=e),i.traits.filter(NotifyProduceUnit).forEach(e=>{e[NotifyProduceUnit.onProduce](a,i)}),i.events.dispatch(new FactoryProduceUnitEvent(a)),!0}computeExitCoords(e,t){if(t===FactoryType.InfantryType)return this.computeBarracksDefaultExitCoords(e);if(t===FactoryType.UnitType)return this.computeWarFactoryExitCoords(e);throw new Error("Unsupported factory type "+FactoryType[t])}computeInternalRallyPoint(e,t,i,r){let s,a;if(t===FactoryType.NavalUnitType)a=this.computeNavalInternalRallyPoint(e,i,r);else{if(t===FactoryType.InfantryType)s=this.computeBarracksInternalRallyCoords(e);else{if(t!==FactoryType.UnitType)throw new Error("Unsupported factory type "+FactoryType[t]);s=this.computeWarFactoryInternalRallyCoords(e)}a=r.tiles.getByMapCoords(s.rx,s.ry)}return a??this.findTileAdjacentToBuilding(e,r)}computeDefaultRallyPoint(e,t,i){let r,s;if(t===FactoryType.NavalUnitType)s=this.computeNavalDefaultRallyPoint(e,i);else{if(t===FactoryType.InfantryType)r=this.computeBarracksInternalRallyCoords(e);else{if(t!==FactoryType.UnitType)throw new Error("Unsupported factory type "+FactoryType[t]);r=this.computeWarFactoryDefaultRallyCoords(e)}s=i.tiles.getByMapCoords(r.rx,r.ry)}return s??this.findTileAdjacentToBuilding(e,i)}findTileAdjacentToBuilding(e,t){return new RadialTileFinder(t.tiles,t.mapBounds,e.tile,e.getFoundation(),1,1,()=>!0).getNextTile()}computeBarracksDefaultExitCoords(e){var t=e.getFoundation();let i,r;return t.width<=2||t.height<=2?(i=t.width-1,r=t.height-1,e.rules.gdiBarracks&&2<t.width&&(i=Math.floor(t.width/2))):(i=0,r=t.height-1),{rx:e.tile.rx+i,ry:e.tile.ry+r}}computeBarracksInternalRallyCoords(e){var t=e.getFoundation();let{rx:i,ry:r}=this.computeBarracksDefaultExitCoords(e);return!(t.width<=2||t.height<=2)||e.rules.gdiBarracks?r+=1:e.rules.nodBarracks&&(i+=t.width<=2?1:0,r+=t.height<=2?1:0),{rx:i,ry:r}}computeWarFactoryExitCoords(e){var t=e.getFoundation();return{rx:e.tile.rx+Math.floor(t.width/2),ry:e.tile.ry+Math.floor(t.height/2)}}computeWarFactoryInternalRallyCoords(e){var t=e.getFoundation();return{rx:e.tile.rx+t.width-1,ry:e.tile.ry+Math.floor(t.height/2)}}computeWarFactoryDefaultRallyCoords(e){var t=e.getFoundation();return{rx:e.tile.rx+t.width,ry:e.tile.ry+Math.floor(t.height/2)}}computeNavalDefaultRallyPoint(e,t){let i=new CardinalTileFinder(t.tiles,t.mapBounds,e.centerTile,5,5,e=>e.terrainType===TerrainType.Water&&!t.getObjectsOnTile(e).find(e=>e.isBuilding()||e.isOverlay()&&e.isBridge()));return i.diagonal=!1,i.getNextTile()??t.tiles.getByMapCoords(e.tile.rx+e.getFoundation().width,e.tile.ry+e.getFoundation().height)}computeNavalInternalRallyPoint(e,t,i){t=new Vector2(t.rx,t.ry).sub(new Vector2(e.centerTile.rx,e.centerTile.ry));return i.tiles.getByMapCoords(e.centerTile.rx+Math.sign(t.x)*(Math.floor(e.getFoundation().width/2)+1),e.centerTile.ry+Math.sign(t.y)*(Math.floor(e.getFoundation().height/2)+1))}}(NotifyBuildStatus=NotifyBuildStatus||{}).onStatusChange=Symbol();class RadialBackFirstTileFinder{constructor(e,t,i,r,s,a,n,o=!0){this.tiles=e,this.mapBounds=t,this.startTile=i,this.foundation=r,this.maxDistance=a,this.predicate=n,this.checkBounds=o,this.distance=s,this.generator=this.generate()}getNextTile(){return this.generator.next().value}*generate(){var r=(e,t)=>{t=this.tiles.getByMapCoords(e,t);if(t&&(!this.checkBounds||this.mapBounds.isWithinBounds(t))&&this.predicate(t))return t};do{var s=this.startTile.rx-this.distance,a=this.startTile.ry-this.distance,n=this.startTile.rx+this.foundation.width-1+this.distance,o=this.startTile.ry+this.foundation.height-1+this.distance;let e,t,i;if(0<this.distance){for(t=1+a;t<o;t++)i=r(s,t),i&&(yield i);for(e=s;e<n;e++)i=r(e,a),i&&(yield i);for(t=o-1;t>=a;t--)i=r(n,t),i&&(yield i);for(e=n;e>=s;e--)i=r(e,o),i&&(yield i)}else this.predicate(this.startTile)&&(yield this.startTile)}while(this.distance++,this.distance<=this.maxDistance)}}class FreeUnitTrait{[NotifyBuildStatus.onStatusChange](t,s,a){if(s.buildStatus===BuildStatus.Ready&&t===BuildStatus.BuildUp&&!s.owner.isNeutral){let e;if(a.rules.hasObject(s.rules.freeUnit,ObjectType.Vehicle))e=a.rules.getObject(s.rules.freeUnit,ObjectType.Vehicle);else{if(!a.rules.hasObject(s.rules.freeUnit,ObjectType.Infantry))return void console.warn(`Free unit "${s.rules.freeUnit}" is not a vehicle or infantry type.`);e=a.rules.getObject(s.rules.freeUnit,ObjectType.Infantry)}let i=a.createUnitForPlayer(e,s.owner),r;t=new RadialBackFirstTileFinder(a.map.tiles,a.map.mapBounds,s.tile,s.getFoundation(),1,1,e=>{var t=0<a.map.terrain.getPassableSpeed(e,i.rules.speedType,i.isInfantry(),!1)&&Math.abs(e.z-s.tile.z)<2&&!a.map.terrain.findObstacles({tile:e,onBridge:void 0},i).length;return!r&&t&&(r=e),t&&!a.map.getObjectsOnTile(e).find(e=>e.isOverlay())}).getNextTile()??r;if(!t)return s.owner.removeOwnedObject(i),i.dispose(),void(s.owner.credits+=i.purchaseValue);a.spawnObject(i,t)}}}class CrewedTrait{[NotifySell.onSell](e,t){this.spawnSurvivors(e,t)}[NotifyDestroy.onDestroy](e,t,i,r){r||i?.obj===e&&i.weapon?.rules.suicide||e.isVehicle()&&e.moveTrait.isMoving()||e.crashableTrait||this.spawnSurvivors(e,t)}spawnSurvivors(r,s){var e=s.rules.general.crew,t=r.owner.country.side;let i,a;if(t===SideType.GDI)i=e.alliedSurvivorDivisor,a=e.alliedCrew;else if(t===SideType.Nod)i=e.sovietSurvivorDivisor,a=e.sovietCrew;else{if(t!==SideType.ThirdSide)return;i=e.thirdSurvivorDivisor,a=e.thirdCrew}let n=s.sellTrait.computeRefundValue(r)/i;n=0<n&&n<1?1:Math.floor(n),n=r.isVehicle()?Math.min(1,n):Math.min(5,n);let o=[];for(let e=0;e<n;e++)o.push(a);if(0<o.length){r.rules.constructionYard&&(o[o.length-1]=s.rules.general.engineer);var l,h=s.map.tiles.getInRectangle(r.tile,r.getFoundation()).filter(e=>s.map.isWithinBounds(e));let i=[...h];for(l of o){var c=s.rules.getObject(l,ObjectType.Infantry);if(s.map.terrain.getPassableSpeed(r.tile,c.speedType,!0,!r.isBuilding()&&r.onBridge,void 0,!0)){let e=s.createUnitForPlayer(c,r.owner),t=i.length?i.splice(s.generateRandomInt(0,i.length-1),1)[0]:void 0;t=t||h[s.generateRandomInt(0,h.length-1)],e.isInfantry()&&(e.position.subCell=Infantry_Infantry.SUB_CELLS[0]),e.veteranTrait&&r.owner.canProduceVeteran(e.rules)&&e.veteranTrait.setVeteranLevel(VeteranLevel.Veteran),s.spawnObject(e,t),r.isBuilding()&&e.unitOrderTrait.addTask(new ScatterTask(s,void 0,{ignoredBlockers:r.isDestroyed?void 0:[r]}))}}}}}class CabHutTrait{constructor(e,t){this.gameObject=e,this.bridges=t,this.checkedClosestBridge=!1}canRepairBridge(){var e=this.findClosestBridgeBounds();return e?this.bridges.canBeRepaired(e):(console.warn(`No bridge associated with hut at ${this.gameObject.tile.rx}, ${this.gameObject.tile.ry}.`),!1)}repairBridge(t,i){var r=this.findClosestBridgeBounds();if(!r)throw new Error("No bridge bounds found");var e=this.bridges.findDestroyedPieceTiles(r),s=r.start.rx!==r.end.rx;let a;a=r.isHigh?BridgeOverlayTypes.calculateHighBridgeOverlayId(r.type,s):BridgeOverlayTypes.calculateLowBridgeOverlayId(r.type,s);var n,o,l=t.rules.getOverlayName(a);for(n of e){let e=t.createObject(ObjectType.Overlay,l);e.overlayId=a,e.value=0,e.position.tileElevation=r.isHigh?4:0,t.spawnObject(e,n),this.updateUnitsUnderBridgePiece(n,r,t,i)}for(o of this.bridges.findBridgePieces(r))o.obj.bridgeTrait.bridgeSpec=r}updateUnitsUnderBridgePiece(e,i,r,s){var a;for(let t of this.bridges.getPieceTiles(this.bridges.getPieceAtTile(e)))if(i.isHigh){let e=r.map.getGroundObjectsOnTile(t).filter(e=>e.tile===t&&e.isUnit()&&!e.unitOrderTrait.hasTasks()&&e.rules.tooBigToFitUnderBridge);e.forEach(e=>e.unitOrderTrait.addTask(new ScatterTask(r)))}else for(a of r.map.getGroundObjectsOnTile(t))a.isUnit()&&(r.map.terrain.getPassableSpeed(t,a.rules.speedType,a.isInfantry(),!0)?(a.zone=ZoneType.Ground,a.onBridge=!0):a.isDestroyed||r.destroyObject(a,{player:s}))}demolishBridge(e,t){var i=this.getBridgePieces();if(i)for(var r of i)r.obj.isLowBridge()&&e.map.getTileZone(r.obj.tile,!0)!==ZoneType.Water||r.obj.isDestroyed||(r.obj.deathType=DeathType.Demolish,e.destroyObject(r.obj,t,!0))}getBridgePieces(){var e=this.findClosestBridgeBounds();if(e)return this.bridges.findBridgePieces(e)}findClosestBridgeBounds(){return this.checkedClosestBridge||(this.checkedClosestBridge=!0,this.closestBridge=this.bridges.findClosestBridgeSpec(this.gameObject.tile)),this.closestBridge}dispose(){this.gameObject=void 0}}class OilDerrickTrait{constructor(){this.isActive=!1,this.produceCashCooldown=0}[NotifySpawn.onSpawn](e){e.owner.isNeutral||(this.isActive=!0)}[NotifyOwnerChange.onChange](e,t){t.isNeutral&&!e.owner.isNeutral&&(e.owner.credits=Math.max(0,e.owner.credits+e.rules.produceCashStartup),0<e.rules.produceCashStartup&&(e.owner.creditsGained+=e.rules.produceCashStartup),this.isActive=!0,this.produceCashCooldown=e.rules.produceCashDelay)}[NotifyTick_NotifyTick.onTick](e){this.isActive&&(this.produceCashCooldown--,this.produceCashCooldown<=0&&(this.produceCashCooldown=e.rules.produceCashDelay,e.owner.credits=Math.max(0,e.owner.credits+e.rules.produceCashAmount),0<e.rules.produceCashAmount&&(e.owner.creditsGained+=e.rules.produceCashAmount)))}}const wallTypes=[[0,0,0,0],[1,0,0,0],[0,1,0,0],[1,1,0,0],[0,0,1,0],[1,0,1,0],[0,1,1,0],[1,1,1,0],[0,0,0,1],[1,0,0,1],[0,1,0,1],[1,1,0,1],[0,0,1,1],[1,0,1,1],[0,1,1,1],[1,1,1,1]];class WallTrait{constructor(){this.linkedDamageHandled=!1,this.wallType=0}[NotifySpawn.onSpawn](e,t){e.isBuilding()?this.connectWall(e,t.map):this.wallType=e.value}[NotifyUnspawn.onUnspawn](e,t){this.updateAdjacentWalls(e,t.map)}[NotifyDamage.onDamage](e,t,i,r){if(!this.linkedDamageHandled){var s=Math.floor(i/2);if(s)for(var a of t.map.tiles.getAllNeighbourTiles(e.tile))if(a.landType===LandType.Wall){let e=t.map.getObjectsOnTile(a).find(e=>(e.isBuilding()||e.isOverlay())&&e.wallTrait);e.wallTrait.linkedDamageHandled=!0,e.healthTrait.inflictDamage(s,r,t),e.wallTrait.linkedDamageHandled=!1,e.healthTrait.health||t.destroyObject(e,r)}}}updateAdjacentWalls(t,e){let i=new CardinalTileFinder(e.tiles,e.mapBounds,t.tile,1,1);for(i.diagonal=!1;r=i.getNextTile();){var r=e.getObjectsOnTile(r).find(e=>(e.isBuilding()||e.isOverlay())&&e.name===t.rules.name);r&&this.connectWall(r,e)}}connectWall(e,i){let t=this.getAdjacentWallData(e.tile,e.name,i);this.updateWallType(e,t.map(e=>e.direction)),t.forEach(e=>{let t=this.getAdjacentWallData(e.tile,e.wall.name,i);this.updateWallType(e.wall,t.map(e=>e.direction))})}updateWallType(e,t){let i=[0,0,0,0];for(var r of t)0===r[0]&&-1===r[1]&&(i[0]=1),1===r[0]&&0===r[1]&&(i[1]=1),0===r[0]&&1===r[1]&&(i[2]=1),-1===r[0]&&0===r[1]&&(i[3]=1);t=this.findWallType(i);e.wallTrait.wallType=t,e.isOverlay()&&(e.value=t)}findWallType(t){for(let e=0;e<wallTypes.length;++e){var i=wallTypes[e];if(i[0]===t[0]&&i[1]===t[1]&&i[2]===t[2]&&i[3]===t[3])return e}return console.warn("Invalid wall directions",t),0}getAdjacentWallData(e,t,i){var r;let s=[];for(r of[[0,1],[0,-1],[1,0],[-1,0]]){var a={x:e.rx+r[0],y:e.ry+r[1]},n=i.tiles.getByMapCoords(a.x,a.y);n&&((a=i.getObjectsOnTile(n).find(e=>(e.isBuilding()||e.isOverlay())&&e.name===t))&&s.push({direction:r,tile:n,wall:a}))}return s}}const CHARGERS_TO_POWER_ON=2,CHARGERS_TO_OVERPOWER=1;class OverpoweredTrait{constructor(e){this.obj=e,this.chargers=new Set}isOverpowered(){let e=CHARGERS_TO_OVERPOWER;return this.obj?.poweredTrait?.isPoweredOn(!0)||(e+=CHARGERS_TO_POWER_ON),this.chargers.size>=e}hasChargersToPowerOn(){return this.chargers.size>=CHARGERS_TO_POWER_ON}chargeFrom(e){this.chargers.add(e),this.swapAttackTaskWeapon()}[NotifyTick_NotifyTick.onTick](i){if(0<this.chargers.size){let t=!1;this.chargers.forEach(e=>{(e.isDestroyed||e.isCrashing||e.owner!==i.owner||e.attackTrait?.currentTarget?.obj!==i)&&(this.chargers.delete(e),t=!0)}),t&&this.swapAttackTaskWeapon()}}swapAttackTaskWeapon(){let e=this.obj?.unitOrderTrait.getCurrentTask();var t;e instanceof AttackTask&&((t=this.getWeapon())?e.setWeapon(t):e.cancel())}getWeapon(){return this.isOverpowered()?this.obj?.secondaryWeapon:this.obj?.primaryWeapon}dispose(){this.obj=void 0,this.chargers.clear()}}class UnitRepairFinishEvent{constructor(e,t){this.target=e,this.from=t,this.type=EventType.UnitRepairFinish}}class UnitRepairStartEvent{constructor(e){this.target=e,this.type=EventType.UnitRepairStart}}!function(e){e[e.Idle=0]="Idle",e[e.Repairing=1]="Repairing"}(RepairStatus=RepairStatus||{});class UnitRepairTrait{constructor(){this.status=RepairStatus.Idle,this.cooldownTicks=0,this.lastRepairTickSuccessful=!1}[NotifySpawn.onSpawn](e,t){this.resetRallyPoint(e,t)}resetRallyPoint(e,t){var i;e.factoryTrait||(i=this.computeDefaultRallyPoint(e,t.map),e.rallyTrait.changeRallyPoint(i,e,t))}[NotifyTick_NotifyTick.onTick](t,i){if(t.dockTrait&&(!t.rules.needsEngineer||!t.owner.isNeutral))if(!t.dockTrait.hasDockedUnits()||t.dockTrait.getDockedUnits().some(e=>e.zone===ZoneType.Air)||t.poweredTrait&&!t.poweredTrait.isPoweredOn())this.status=RepairStatus.Idle;else if(this.cooldownTicks<=0){var r,s,a=i.rules.general.repair,a=t.rules.unitReload?a.reloadRate:a.uRepairRate;this.cooldownTicks+=GameSpeed.BASE_TICKS_PER_SECOND*a*60;let e=!1;for(r of t.dockTrait.getDockedUnits())r.zone!==ZoneType.Air&&(r.healthTrait.health<100&&i.areFriendly(r,t)?(this.tickRepair(r,i,t)&&(e=!0),!e||this.status!==RepairStatus.Idle&&this.lastRepairTickSuccessful||t.helipadTrait||i.events.dispatch(new UnitRepairStartEvent(r))):((s=t.rallyTrait.findRallyNodeForUnit(r,i.map))&&(t.dockTrait.undockUnit(r),r.unitOrderTrait.addTask(new MoveTask(i,s.tile,!!s.onBridge,{closeEnoughTiles:i.rules.general.closeEnough}))),t.helipadTrait||i.events.dispatch(new UnitRepairFinishEvent(r,t))));this.lastRepairTickSuccessful=e,this.status=e?RepairStatus.Repairing:RepairStatus.Idle}else this.cooldownTicks--}tickRepair(e,t,i){var r=t.rules.general.repair,s=Math.floor(r.repairStep),a=r.repairPercent;let n;if(a){r=a*e.purchaseValue/e.healthTrait.maxHitPoints,a=Math.min(e.owner.credits,Math.max(1,Math.floor(r*s)));if(n=r&&a?Math.floor(a/r):s,!a)return!1;e.owner.credits-=a}else n=s;return n=Math.min(n,e.healthTrait.maxHitPoints-e.healthTrait.getHitPoints()),!!n&&(e.healthTrait.healBy(n,i,t),!0)}computeDefaultRallyPoint(e,t){var i=e.getFoundation(),i=new Vector2(e.tile.rx,e.tile.ry+i.height);return t.tiles.getByMapCoords(i.x,i.y)??e.tile}}class RallyTrait{getRallyPoint(){return this.rallyPoint}changeRallyPoint(e,t,i){i=this.findValidRallyPoint(t,e,i.map);i&&(this.rallyPoint=i)}findValidRallyPoint(i,e,r){let t=new RadialTileFinder(r.tiles,r.mapBounds,e,{width:1,height:1},0,20,e=>(i.rules.naval||e.terrainType!==TerrainType.Water)&&!r.tileOccupation.isTileOccupiedBy(e,i)),s=t.getNextTile();if(!s&&i.factoryTrait?.type===FactoryType.NavalUnitType){var{width:a,height:n}=i.getFoundation();for(let t=0;t<a;t++)for(let e=0;e<n;e++){var o=r.tiles.getByMapCoords(i.tile.rx+t,i.tile.ry+e);if(!o)break;if(0<r.terrain.getPassableSpeed(o,SpeedType.Float,!1,!1)){s=o;break}}}return s}findRallyNodeForUnit(e,t){if(this.rallyPoint){var i=this.findRallyPointforUnit(e,this.rallyPoint,t,!0);return{tile:i,onBridge:e.rules.naval?void 0:t.tileOccupation.getBridgeOnTile(i)}}}findRallyPointforUnit(i,e,r,s,a){let n=i.rules.naval?void 0:r.tileOccupation.getBridgeOnTile(e),o=i.rules.movementZone===MovementZone.Fly,t=new RadialTileFinder(r.tiles,r.mapBounds,e,{width:1,height:1},0,5,e=>{var t=!n||n.isHighBridge()?r.tileOccupation.getBridgeOnTile(e):void 0;return!(o?[]:r.terrain.findObstacles({tile:e,onBridge:t},i)).length&&(void 0===a||Math.abs(a-(e.z+(t?.tileElevation??0)))<4)&&(!s||!r.getObjectsOnTile(e).find(e=>e.isBuilding()&&!e.isDestroyed))&&(o||0<r.terrain.getPassableSpeed(e,i.rules.speedType,i.isInfantry(),!!t))});return t.getNextTile()??e}}class Timer{constructor(){this.activeTicks=0}isActive(){return 0<this.activeTicks}setActiveFor(e,t){this.activeTicks=e,this.activeFor=e,this.activeSince=t}reset(){this.activeTicks=0,this.activeSince=void 0,this.activeFor=void 0}getTicksLeft(){return this.activeTicks}getInitialTicks(){return this.activeFor??0}tick(e){return 0<this.activeTicks&&(this.activeTicks--,this.activeTicks<=0||void 0!==this.activeSince&&e-this.activeSince>this.activeFor)&&(this.reset(),!0)}}class C4ChargeTrait{constructor(){this.timer=new Timer}hasCharge(){return this.timer.isActive()}setCharge(e,t){this.hasCharge()||(this.timer.setActiveFor(e),this.attackerInfo=t)}[NotifyTick_NotifyTick.onTick](e,t){this.timer.isActive()&&!0===this.timer.tick(t.currentTick)&&(e.invulnerableTrait.isActive()||(e.isBuilding()&&e.cabHutTrait?e.cabHutTrait.demolishBridge(t,this.attackerInfo):(e.deathType=DeathType.Demolish,t.destroyObject(e,this.attackerInfo,!0))))}}class HelipadTrait{[NotifyOwnerChange.onChange](e,t,i){this.checkAircraftsForPlayer(t,i)}[NotifyUnspawn.onUnspawn](e,t){this.checkAircraftsForPlayer(e.owner,t)}checkAircraftsForPlayer(e,t){let i=t.rules.general.padAircraft;var r;for(r of e.getOwnedObjectsByType(ObjectType.Aircraft).filter(e=>i.includes(e.name)))r.airportBoundTrait&&(r.airportBoundTrait.preferredAirport=void 0)}}class UnitReloadTrait{[NotifyTick_NotifyTick.onTick](t,i){if(t.dockTrait&&t.dockTrait.hasDockedUnits()&&!t.dockTrait.getDockedUnits().every(e=>!this.canReloadUnit(e)))if(void 0===this.cooldownTicks&&(this.cooldownTicks=GameSpeed.BASE_TICKS_PER_SECOND*i.rules.general.repair.reloadRate*60),this.cooldownTicks<=0){this.cooldownTicks=GameSpeed.BASE_TICKS_PER_SECOND*i.rules.general.repair.reloadRate*60;let e=t.dockTrait.getDockedUnits();var r;for(r of 0===e[0].ammo?e.slice(0,1):e)this.canReloadUnit(r)&&r.ammoTrait.ammo++}else this.cooldownTicks--}canReloadUnit(e){return!(!e.ammoTrait||!e.rules.manualReload||e.ammoTrait.isFull()||e.zone===ZoneType.Air)}}class WaitForBuildUpTask extends TaskGroup{constructor(e,t){super(new WaitMinutesTask(e),new CallbackTask(e=>e.setBuildStatus(BuildStatus.Ready,t))),this.cancellable=!1}}class SuperWeaponTrait{constructor(e){this.name=e}getSuperWeapon(e){return e.owner.superWeaponsTrait?.get(this.name)}[NotifySpawn.onSpawn](e,t){this.addSuperWeaponToPlayerIfNeeded(e.owner,t)}[NotifyUnspawn.onUnspawn](e,t){this.removeSuperWeaponFromPlayerIfNeeded(e.owner)}[NotifyOwnerChange.onChange](e,t,i){this.removeSuperWeaponFromPlayerIfNeeded(t),this.addSuperWeaponToPlayerIfNeeded(e.owner,i)}addSuperWeaponToPlayerIfNeeded(t,i){if(t.superWeaponsTrait&&!t.superWeaponsTrait.has(this.name)){let e=i.createSuperWeapon(this.name,t);t.superWeaponsTrait.add(e),e.rules.isPowered&&t.powerTrait?.isLowPower()&&e.pauseTimer()}}removeSuperWeaponFromPlayerIfNeeded(e){let t=e.superWeaponsTrait;t&&(e.getOwnedObjectsByType(ObjectType.Building).some(e=>e.superWeaponTrait?.name===this.name)||(e=t.get(this.name))&&!e.isGift&&t.remove(this.name))}}const TEMPORARY_REVEAL_SECONDS=5,TEMPORARY_REVEAL_RADIUS=3,OBJECT_REVEAL_RADIUS=4.25,SHROUD_TYPE_BITS=3,SHROUD_TYPE_MASK=(1<<SHROUD_TYPE_BITS)-1;!function(e){e[e.Unexplored=0]="Unexplored",e[e.TemporaryReveal=1]="TemporaryReveal",e[e.Explored=2]="Explored"}(ShroudType=ShroudType||{}),function(e){e[e.Darken=8]="Darken"}(ShroudFlag=ShroudFlag||{});class MapShroud{constructor(){this.invalidations=new Map,this.temporaryReveals=new Map,this.fullInvalidation=!1,this._onChange=new EventDispatcher}get onChange(){return this._onChange.asEvent()}fromTiles(e){var t,i=e.getMapSize(),r=e.getMaxTileHeight(),r=this.padding=(r+r%2)/2;this.size={width:i.width+r,height:i.height+r},this.tiles=new Uint8Array(this.size.width*this.size.height),this.tiles.fill(ShroudType.Unexplored),this.tileElevation=new Uint8Array(this.size.width*this.size.height);for(t of e.getAll()){var s=this.getTileIndex(t);this.tileElevation[s]=Math.max(this.tileElevation[s],t.terrainType===TerrainType.Cliff&&0<t.z?t.z-1:t.z)}return this}getSize(){return this.size}getTileIndex(e){var{sx:t,sy:e}=this.rxyzToSxy(e.rx,e.ry,e.z);return t+e*this.size.width}rxyzToSxy(e,t,i){i=(i|=0)+i%2;return{sx:e-i/2+this.padding,sy:t-i/2+this.padding}}sxyzToRxy(e,t,i){return{rx:e+Math.ceil(i/2)-this.padding,ry:t+Math.ceil(i/2)-this.padding}}shroudCoordsToWorld({sx:e,sy:t}){return this.sxyzToRxy(e,t,0)}findTilesAtShroudCoords({sx:t,sy:i},r){var e=r.getMaxTileHeight(),s=e+e%2;let a=[];for(let e=0;e<=s;e+=2){var n=e+e%2,{rx:o,ry:n}=this.sxyzToRxy(t,i,n),n=r.getByMapCoords(o,n);n?.z===e&&a.push(n)}return a}clone(){let e=new MapShroud;return e.tiles=this.tiles.slice(),e.size=this.size,e.padding=this.padding,e.tileElevation=this.tileElevation,e}copy(e){this.tiles=e.tiles.slice(),this.size=e.size,this.padding=e.padding,this.tileElevation=e.tileElevation}merge(e){if(this.size.width!==e.size.width||this.size.height!==e.size.height)throw new Error("Size mismatch");var i=e.tiles;for(let e=0,t=this.tiles.length;e<t;e++)this.tiles[e]=Math.max(i[e]&SHROUD_TYPE_MASK,this.tiles[e]&SHROUD_TYPE_MASK)|(i[e]|this.tiles[e])>>SHROUD_TYPE_BITS<<SHROUD_TYPE_BITS}isShrouded(e,t=0){t=this.rxyzToSxy(e.rx,e.ry,e.z+t);return this.getShroudTypeByShroudCoords(t)===ShroudType.Unexplored}getShroudType(e){return this.tiles[this.getTileIndex(e)]&SHROUD_TYPE_MASK}isFlagged(e,t){return 0!=(this.tiles[this.getTileIndex(e)]&t)}getShroudTypeByTileCoords(e,t,i){return this.getShroudTypeByShroudCoords(this.rxyzToSxy(e,t,i))}getShroudTypeByShroudCoords({sx:e,sy:t}){return e<0||t<0||e>=this.size.width||t>=this.size.height?ShroudType.Unexplored:this.tiles[e+t*this.size.width]&SHROUD_TYPE_MASK}invalidateFull(){this.fullInvalidation=!0}invalidate(e,t,i){var r=e.sx+e.sy*this.size.width;let s=this.invalidations.get(r);s||(s={center:e,elevation:0,radius:0},this.invalidations.set(r,s)),s.elevation=Math.max(s.elevation,t),s.radius=Math.max(s.radius,i)}revealFrom(e){var t,i;e.isBuilding()&&e.wallTrait||(t=e.sight)&&(i=e.tile.z+e.tileElevation,e=this.rxyzToSxy(e.tile.rx,e.tile.ry,i),this.invalidate(e,i,t))}revealAround(e,t){e=this.rxyzToSxy(e.rx,e.ry,e.z);this.invalidate(e,Number.POSITIVE_INFINITY,t)}unrevealAround(e,t){var i=[],e=this.rxyzToSxy(e.rx,e.ry,e.z);this.setValueAround(e,t,Number.POSITIVE_INFINITY,i,ShroudType.Unexplored,ShroudType.Explored),this._onChange.dispatch(this,{type:"incremental",coords:i})}revealTemporarily(e){e=this.rxyzToSxy(e.tile.rx,e.tile.ry,e.tile.z+e.tileElevation);this.temporaryReveals.set(e,TEMPORARY_REVEAL_SECONDS*GameSpeed.BASE_TICKS_PER_SECOND)}revealObject(e){e=this.rxyzToSxy(e.tile.rx,e.tile.ry,e.tile.z+e.tileElevation);this.invalidate(e,Number.POSITIVE_INFINITY,OBJECT_REVEAL_RADIUS)}toggleFlagsAround(e,t,i,r){var s=[],e=this.rxyzToSxy(e.rx,e.ry,e.z);this.setValueAround(e,t,Number.POSITIVE_INFINITY,s,void 0,void 0,r?{setFlags:i}:{clearFlags:i}),this._onChange.dispatch(this,{type:"incremental",coords:s})}update(){let i=[];if(this.invalidations.size){for(var e of this.invalidations.values())this.setValueAround(e.center,e.radius,e.elevation,i,ShroudType.Explored,[ShroudType.Unexplored,ShroudType.TemporaryReveal]);this.invalidations.clear()}this.temporaryReveals.size&&this.temporaryReveals.forEach((e,t)=>{e<=0?(this.setValueAround(t,TEMPORARY_REVEAL_RADIUS,Number.POSITIVE_INFINITY,i,ShroudType.Unexplored,ShroudType.TemporaryReveal),this.temporaryReveals.delete(t)):(e===TEMPORARY_REVEAL_SECONDS*GameSpeed.BASE_TICKS_PER_SECOND&&this.setValueAround(t,TEMPORARY_REVEAL_RADIUS,Number.POSITIVE_INFINITY,i,ShroudType.TemporaryReveal,ShroudType.Unexplored),this.temporaryReveals.set(t,e-1))}),this.fullInvalidation?(this.fullInvalidation=!1,this._onChange.dispatch(this,{type:"full"})):i.length&&this._onChange.dispatch(this,{type:"incremental",coords:i})}setValueAround(r,s,a,n,o,l=void 0,{setFlags:h,clearFlags:c}={}){var e=Math.ceil(s),t=clamp(r.sx-e,0,this.size.width-1),d=clamp(r.sx+e,0,this.size.width-1),u=clamp(r.sy-e,0,this.size.height-1),p=clamp(r.sy+e,0,this.size.height-1),g=this.size.width;for(let i=t;i<=d;i++)for(let t=u;t<=p;t++){var m=i+t*g,y=this.tiles[m]&SHROUD_TYPE_MASK,T=this.tiles[m]>>SHROUD_TYPE_BITS<<SHROUD_TYPE_BITS;let e=T;void 0!==h&&(e|=h),void 0!==c&&(e&=~c),void 0!==l&&("number"!=typeof l?!l.includes(y):l!==y)||((i-r.sx)*(i-r.sx)+(t-r.sy)*(t-r.sy)>s*s+1||this.tileElevation[m]>=a+4||(this.tiles[m]=(o??y)|e,y===o&&T===e||n.push({sx:i,sy:t})))}}revealAll(){this.tiles.fill(ShroudType.Explored),this._onChange.dispatch(this,{type:"clear"})}reset(){this.tiles.fill(ShroudType.Unexplored),this._onChange.dispatch(this,{type:"cover"})}}const GAP_REFRESH_SECONDS=5;class GapGeneratorTrait{constructor(e){this.radiusTiles=e,this.refreshTicks=0}[NotifyTick_NotifyTick.onTick](e,t){0<this.refreshTicks&&this.refreshTicks--,this.refreshTicks<=0&&this.update(e,t)}[NotifySpawn.onSpawn](e,t){this.markGapTilesForFriendlies(e,e.owner,t,!0)}[NotifyUnspawn.onUnspawn](e,t){this.markGapTilesForFriendlies(e,e.owner,t,!1),this.update(e,t)}[NotifyOwnerChange.onChange](e,t,i){this.markGapTilesForFriendlies(e,t,i,!1),this.markGapTilesForFriendlies(e,e.owner,i,!0),this.update(e,i)}[NotifyWarpChange_NotifyWarpChange.onChange](e,t,i){this.markGapTilesForFriendlies(e,e.owner,t,!i),i&&this.update(e,t)}markGapTilesForFriendlies(i,e,r,t){let s=[e,...r.alliances.getAllies(e)],a;for(var n of s){let e=r.mapShroudTrait.getPlayerShroud(n);if(e&&(e.toggleFlagsAround(i.tile,this.radiusTiles,ShroudFlag.Darken,t),!t)){if(!a){let t=new RangeHelper(r.map.tileOccupation);a=s.map(e=>[...e.buildings]).flat().filter(e=>e.gapGeneratorTrait&&e!==i&&t.tileDistance(e,i)<=e.gapGeneratorTrait.radiusTiles+this.radiusTiles)}for(var o of a)e.toggleFlagsAround(o.tile,o.gapGeneratorTrait.radiusTiles,ShroudFlag.Darken,!0)}}}update(t,i){this.refreshTicks=GAP_REFRESH_SECONDS*GameSpeed.BASE_TICKS_PER_SECOND;let r;var s,a,n,o,l=t.owner.buildings.has(t)&&t.poweredTrait?.isPoweredOn();for(s of i.getCombatants())if(s!==t.owner&&!i.alliances.areAllied(t.owner,s)){let e=i.mapShroudTrait.getPlayerShroud(s);if(e)if(l){e.unrevealAround(t.tile,this.radiusTiles),r||(n=this.radiusTiles+TechnoRules.MAX_SIGHT,a=new Vector2(t.tile.rx,t.tile.ry).addScalar(-n),n=new Vector2(t.tile.rx,t.tile.ry).addScalar(n),r=i.map.technosByTile.queryRange(new Box2(a,n)));for(o of r)o.owner===s||i.alliances.areAllied(o.owner,s)?e.revealFrom(o):o.rules.revealToAll&&e.revealObject(o)}else[...s.buildings].some(e=>e.rules.spySat)&&e.revealAround(t.tile,this.radiusTiles)}}}const SCAN_FRAMES=GameSpeed.BASE_TICKS_PER_SECOND;class PsychicDetectorTrait{constructor(e){this.radiusTiles=e,this.detectionLines=[],this.nextScan=SCAN_FRAMES}[NotifyTick_NotifyTick.onTick](e,t){e.owner.powerTrait?.isLowPower()?this.disable():(0<this.nextScan&&this.nextScan--,this.nextScan<=0&&(this.nextScan=SCAN_FRAMES,this.detectionLines=this.scan(e,t)))}[NotifyWarpChange_NotifyWarpChange.onChange](e,t,i){i&&this.disable()}disable(){this.detectionLines.length&&(this.detectionLines=[],this.nextScan=0)}scan(t,i){var e=i.getCombatants().filter(e=>e!==t.owner&&!i.alliances.areAllied(e,t.owner));let r=[],s=new RangeHelper(i.map.tileOccupation);var a,n,o,l=e=>s.distance2(e,t)/Coords.LEPTONS_PER_TILE<=this.radiusTiles;for(a of e)for(var h of a.getOwnedObjects())h.attackTrait?.currentTarget?l((n=h.attackTrait.currentTarget).obj??n.tile)&&r.push({source:h,target:n}):h.isUnit()&&h.unitOrderTrait.targetLinesConfig&&((o=h.unitOrderTrait.targetLinesConfig).target?l(o.target)&&(n=i.createTarget(o.target,o.target.tile),r.push({source:h,target:n})):(o=o.pathNodes[0])&&l(o.tile)&&(o=i.createTarget(o.onBridge,o.tile),r.push({source:h,target:o})));return r}}const HEALING_SECONDS=5;class HospitalTrait{constructor(){this.healQueue=[]}addToHealQueue(e){return this.healQueue.push(e),this.healQueue.length-1}unitIsFirstInHealQueue(e){return this.healQueue[0]===e}removeFromHealQueue(e){e=this.healQueue.indexOf(e);-1!==e&&this.healQueue.splice(e,1)}startHealing(e){if(this.unit)throw new Error(`Already busy healing unit ${ObjectType[this.unit.type]}#${this.unit.id}}`);this.unit=e,this.healTicks=HEALING_SECONDS*GameSpeed.BASE_TICKS_PER_SECOND}[NotifyTick_NotifyTick.onTick](e,t){var i;this.healQueue=this.healQueue.filter(e=>!e.isDestroyed&&!e.isCrashing),this.unit&&void 0!==this.healTicks&&(0<this.healTicks&&this.healTicks--,this.healTicks<=0&&(this.healTicks=void 0,this.removeFromHealQueue(this.unit),this.unit.healthTrait.healToFull(e,t),e.ammoTrait&&e.ammoTrait.ammo--,this.evacuate(this.unit,e,t),i=this.unit,this.unit=void 0,t.events.dispatch(new UnitRepairFinishEvent(i,e))))}[NotifyDestroy.onDestroy](e,t,i){this.unit&&(this.unit.deathType=e.deathType,t.destroyObject(this.unit,i,!0),this.unit=void 0)}evacuate(t,i,r){let e;var s={x:i.tile.rx,y:i.tile.ry+i.art.foundation.height},s=r.map.tiles.getByMapCoords(s.x,s.y);s&&r.map.isWithinBounds(s)&&this.canEvacuateTo(s,t,i,r)&&(e=s),e=e||new RadialTileFinder(r.map.tiles,r.map.mapBounds,i.tile,i.art.foundation,1,1,e=>this.canEvacuateTo(e,t,i,r)).getNextTile(),e?(r.unlimboObject(t,e),t.unitOrderTrait.addTask(new ScatterTask(r))):r.destroyObject(t,{player:t.owner})}canEvacuateTo(e,t,i,r){return 0<r.map.terrain.getPassableSpeed(e,t.rules.speedType,t.isInfantry(),!1)&&Math.abs(e.z-i.tile.z)<2&&!r.map.terrain.findObstacles({tile:e,onBridge:void 0},t).length}}class DelayedKillTrait{constructor(){this.timer=new Timer}isActive(){return this.timer.isActive()}activate(e,t){this.isActive()||(this.timer.setActiveFor(e),this.attackerInfo=t)}[NotifyTick_NotifyTick.onTick](e,t){this.timer.isActive()&&!0===this.timer.tick(t.currentTick)&&(e.invulnerableTrait.isActive()||e.isBuilding()&&e.cabHutTrait||t.destroyObject(e,this.attackerInfo,!0,!0))}}!function(e){e[e.BuildUp=0]="BuildUp",e[e.Ready=1]="Ready",e[e.BuildDown=2]="BuildDown"}(BuildStatus=BuildStatus||{});class Building extends Techno_Techno{get buildStatus(){return this._buildStatus}static factory(e,t,i,r,s,a){let n=new this(e,t,r);return t.canBeOccupied&&(n.garrisonTrait=new GarrisonTrait(n,i.audioVisual.conditionRed,t.maxNumberOccupants),n.traits.add(n.garrisonTrait)),t.canC4&&!t.wall&&(n.c4ChargeTrait=new C4ChargeTrait,n.traits.add(n.c4ChargeTrait)),t.eligibleForDelayKill&&(n.delayedKillTrait=new DelayedKillTrait,n.traits.add(n.delayedKillTrait)),t.bridgeRepairHut&&(n.cabHutTrait=new CabHutTrait(n,a),n.traits.add(n.cabHutTrait)),t.crewed&&(n.crewedTrait=new CrewedTrait,n.traits.add(n.crewedTrait)),t.turret&&(n.turretTrait=new TurretTrait,n.traits.add(n.turretTrait)),t.overpowerable&&(n.overpoweredTrait=new OverpoweredTrait(n),n.traits.add(n.overpoweredTrait)),(t.powered&&0!==t.power||t.needsEngineer)&&(n.poweredTrait=new PoweredTrait(n),n.traits.add(n.poweredTrait)),(t.factory||t.cloning)&&(n.factoryTrait=new FactoryTrait(t.cloning?FactoryType.InfantryType:t.factory,t.cloning),n.traits.add(n.factoryTrait)),t.superWeapon&&(n.superWeaponTrait=new SuperWeaponTrait(t.superWeapon),n.traits.add(n.superWeaponTrait)),t.numberOfDocks&&(n.dockTrait=new DockTrait(n,s,t.numberOfDocks,r.dockingOffsets),n.traits.add(n.dockTrait),t.helipad&&(n.helipadTrait=new HelipadTrait,n.traits.add(n.helipadTrait)),(t.unitRepair||t.unitReload)&&(n.unitRepairTrait=new UnitRepairTrait,n.traits.add(n.unitRepairTrait)),t.unitReload&&(n.unitReloadTrait=new UnitReloadTrait,n.traits.add(n.unitReloadTrait))),t.hospital&&(n.hospitalTrait=new HospitalTrait,n.traits.add(n.hospitalTrait)),(t.factory||t.cloning||t.numberOfDocks)&&(n.rallyTrait=new RallyTrait,n.traits.add(n.rallyTrait)),t.freeUnit&&n.traits.add(new FreeUnitTrait),t.produceCashStartup&&n.traits.add(new OilDerrickTrait),t.wall&&(n.wallTrait=new WallTrait,n.traits.add(n.wallTrait)),t.gapGenerator&&(n.gapGeneratorTrait=new GapGeneratorTrait(t.gapRadiusInCells),n.traits.add(n.gapGeneratorTrait)),t.psychicDetectionRadius&&(n.psychicDetectorTrait=new PsychicDetectorTrait(t.psychicDetectionRadius),n.traits.add(n.psychicDetectorTrait)),n}constructor(e,t,i){super(ObjectType.Building,e,t,i),this.showWeaponRange=!1,this.direction=0,this._buildStatus=BuildStatus.BuildUp,this.lastBuildStatus=this.buildStatus}isBuilding(){return!0}getFoundation(){return this.art.foundation}getFoundationCenterOffset(){var e=this.getFoundation();return new Vector2(e.width/2*Coords.LEPTONS_PER_TILE,e.height/2*Coords.LEPTONS_PER_TILE)}update(e){this.buildStatus!==BuildStatus.BuildUp||this.unitOrderTrait.hasTasks()||this.unitOrderTrait.addTask(new WaitForBuildUpTask(e.rules.general.buildupTime,e)),this.attackTrait?.setDisabled(this.buildStatus!==BuildStatus.Ready||!!this.poweredTrait&&!this.poweredTrait.isPoweredOn()),super.update(e)}setBuildStatus(e,t){this._buildStatus=e;let i=this.lastBuildStatus;this.buildStatus!==i&&(this.lastBuildStatus=this.buildStatus,this.traits.filter(NotifyBuildStatus).forEach(e=>{e[NotifyBuildStatus.onStatusChange](i,this,t)}),t.events.dispatch(new BuildStatusChangeEvent(this,this.buildStatus)))}}class Terrain_Terrain extends GameObject{static factory(e,t,i){return new this(e,t,i)}constructor(e,t,i){super(ObjectType.Terrain,e,t,i),this.radarInvisible=this.rules.radarInvisible}}class Overlay_Overlay extends GameObject{static factory(e,t,i){let r=new this(e,t,i);return t.wall&&(r.wallTrait=new WallTrait,r.traits.add(r.wallTrait)),r}constructor(e,t,i){super(ObjectType.Overlay,e,t,i),this.radarInvisible=this.rules.radarInvisible}isTiberium(){return void 0!==OreOverlayTypes.getOverlayTibType(this.overlayId)}isBridge(){return BridgeOverlayTypes.isBridge(this.overlayId)}isXBridge(){return BridgeOverlayTypes.isXBridge(this.overlayId)}isHighBridge(){return BridgeOverlayTypes.isHighBridge(this.overlayId)}isLowBridge(){return BridgeOverlayTypes.isLowBridge(this.overlayId)}isBridgePlaceholder(){return BridgeOverlayTypes.isBridgePlaceholder(this.overlayId)}getFoundation(){let e={width:1,height:1};return this.isBridge()&&(this.isXBridge()?e.height+=2:e.width+=2),e}getLandType(){return this.rules.wall?LandType.Wall:this.isTiberium()?LandType.Tiberium:this.isBridge()&&this.isHighBridge()?LandType.Road:this.rules.land}}class Smudge_Smudge extends GameObject{static factory(e,t,i){return new this(e,t,i)}constructor(e,t,i){super(ObjectType.Smudge,e,t,i)}getFoundation(){return{width:this.rules.width,height:this.rules.height}}}class TeleportMoveToRefineryTask extends MoveTask{constructor(e,t,i,r){super(e,i??t,!1,{closeEnoughTiles:i?void 0:0,strictCloseEnough:!i}),this.teleportTile=t,this.teleportCondition=r}onStart(e){if(super.onStart(e),!e.harvesterTrait||e.rules.locomotor!==LocomotorType.Chrono)throw new Error(`Vehicle ${e.name} is not a chrono miner`)}onTick(e){return!e.moveTrait.isDisabled()&&(!(this.isCancelling()||e.moveTrait.moveState!==MoveState.ReachedNextWaypoint||e.tile===this.teleportTile||!this.tryTeleportToRefinery(e))||!0===super.onTick(e)&&(this.isCancelling()||e.tile===this.teleportTile||this.tryTeleportToRefinery(e),!0))}tryTeleportToRefinery(e){return(!this.teleportCondition||!1!==this.teleportCondition(e,this.teleportTile))&&(!this.game.map.terrain.findObstacles({tile:this.teleportTile,onBridge:void 0},e).length&&(e.moveTrait.teleportUnitToTile(this.teleportTile,void 0,!0,!0,this.game),e.zone===ZoneType.Air&&(e.zone=ZoneType.Ground,e.position.tileElevation=0),!0))}}const RETRY_MOVE_SECONDS=5,LOAD_RATE_SECONDS=1,ADJACENT_SCAN_PRIORITIES=[[8,5,6],[3,0,2],[7,4,1]];class GatherOreTask extends Task{constructor(e,t,i=!1){super(),this.game=e,this.initialTarget=t,this.explicitOrder=i,this.forceMoveTried=!1,this.useChildTargetLines=!0,this.preventOpportunityFire=!1,this.rangeHelper=new RangeHelper(e.map.tileOccupation),this.scanNearRadius=e.rules.ai.tiberiumNearScan,this.scanFarRadius=e.rules.ai.tiberiumFarScan}onStart(e){if(!e.isVehicle()||!e.harvesterTrait)throw new Error(`Unit ${e.name} is not a harvester.`);e.harvesterTrait.status=HarvesterStatus.MovingToOreSite,e.harvesterTrait.lastGatherExplicit=this.explicitOrder}onEnd(e){e.harvesterTrait.status!==HarvesterStatus.LookingForOreSite&&(e.harvesterTrait.status=HarvesterStatus.Idle)}onTick(i){if(this.isCancelling())return!0;let r=i.harvesterTrait;if(r.status===HarvesterStatus.MovingToOreSite){var e=this.target;if(this.target=this.findClosestReachableOreSite(i,this.target||this.initialTarget?.landType!==LandType.Tiberium?r.lastOreSite??i.tile:this.initialTarget,!0),r.lastOreSite=this.target,!this.target){r.status=HarvesterStatus.LookingForOreSite;let e=this.getRefineryOnTile(i.tile);if(e&&1===i.unitOrderTrait.getTasks().length){let t=i.rules.movementZone===MovementZone.Fly;var s=new RadialTileFinder(this.game.map.tiles,this.game.map.mapBounds,e.tile,e.getFoundation(),1,5,e=>t||0<this.game.map.terrain.getPassableSpeed(e,i.rules.speedType,i.isInfantry(),!1)&&Math.abs(e.z-i.tile.z)<2&&!this.game.map.terrain.findObstacles({tile:e,onBridge:void 0},i).length).getNextTile();s&&i.unitOrderTrait.addTasks(new MoveTask(this.game,s,!1),new CallbackTask(()=>{[MoveResult.Success,MoveResult.CloseEnough,MoveResult.Cancel].includes(i.moveTrait.lastMoveResult)||this.children.push(new WaitMinutesTask(1/60))}))}return!0}s=this.game.rules.general.closeEnough,e=e&&this.rangeHelper.tileDistance(i.tile,this.target)<=s;if(!(i.tile===this.target||i.tile.landType===LandType.Tiberium&&e)){if(i.tile!==this.target&&e&&i.tile.landType!==LandType.Tiberium){e=this.findClosestReachableOreSite(i,i.tile,!1,!0);if(e)this.target=e,r.lastOreSite=this.target;else{if(!this.forceMoveTried)return this.forceMoveTried=!0,this.children.push(new MoveTask(this.game,this.target,!1,{closeEnoughTiles:0,strictCloseEnough:!0})),!1;if(this.forceMoveTried=!1,!r.isEmpty())return this.returnOreIfPossible(i),!0;e=this.findClosestReachableOreSite(i,i.tile,!0,!0);if(!e)return r.status=HarvesterStatus.LookingForOreSite,!0;this.target=e,r.lastOreSite=this.target}}return this.children.push(new MoveTask(this.game,this.target,!1,{closeEnoughTiles:s}),new CallbackTask(()=>{[MoveResult.Success,MoveResult.CloseEnough,MoveResult.Cancel].includes(i.moveTrait.lastMoveResult)||this.children.push(new WaitMinutesTask(RETRY_MOVE_SECONDS/60))})),!1}this.target=i.tile,r.lastOreSite=this.target,r.status=HarvesterStatus.Harvesting,this.forceMoveTried=!1}if(r.status!==HarvesterStatus.Harvesting)return!1;{if(r.isFull())return this.returnOreIfPossible(i),!0;let e=this.game.map.getObjectsOnTile(i.tile).find(e=>e.isOverlay()&&e.isTiberium());if(!e)return this.findClosestReachableOreSite(i,i.tile,!1)||r.isEmpty()?(r.status=HarvesterStatus.MovingToOreSite,this.onTick(i)):(this.returnOreIfPossible(i),!0);let t=e.traits.get(TiberiumTrait);s=t.collectBail();return(t.getBailCount()||this.game.unspawnObject(e),void 0===s||r.addBails(s,1),[...i.owner.buildings].some(e=>e.rules.refinery)||this.explicitOrder)?(this.children.push(new WaitMinutesTask(LOAD_RATE_SECONDS/60)),!1):!0}}findClosestReachableOreSite(t,i,e,r=!1){let s=t.rules.movementZone===MovementZone.Fly;var a=t.rules.speedType,n=t.isInfantry();let o=!s&&this.game.map.terrain.getPassableSpeed(t.tile,a,n,t.onBridge)?this.game.map.terrain.getIslandIdMap(a,n):void 0,l=o?.get(t.tile,t.onBridge);var h,n=e=>e.landType===LandType.Tiberium&&o?.get(e,!1)===l&&(!r||(s||!this.game.map.terrain.findObstacles({tile:e,onBridge:void 0},t).length));if(n(i))return i;let c=1;if(!e){let e=new RadialTileFinder(this.game.map.tiles,this.game.map.mapBounds,i,{width:1,height:1},c,c,n),t=[];for(;h=e.getNextTile();)t.push(h);if(t.length){let e=t.map(e=>{let t=this.game.map.getObjectsOnTile(e).find(e=>e.isOverlay()&&e.isTiberium());if(!t)throw new Error(`Ore should exist on tile ${e.rx},${e.ry} b/c of landType`);var i=t.traits.get(TiberiumTrait);return{tile:e,ore:t,tibTrait:i}});return e.sort((e,t)=>1e5*(t.tibTrait.rules.value-e.tibTrait.rules.value)+1e3*(t.ore.value-e.ore.value)+(ADJACENT_SCAN_PRIORITIES[1+t.tile.ry-i.ry][1+t.tile.rx-i.rx]-ADJACENT_SCAN_PRIORITIES[1+e.tile.ry-i.ry][1+e.tile.rx-i.rx])),e[0].tile}c=2}e=e?this.scanFarRadius:this.scanNearRadius;let d=new RadialTileFinder(this.game.map.tiles,this.game.map.mapBounds,i,{width:1,height:1},c,e,n);return d.getNextTile()}getRefineryOnTile(e){return this.game.map.getObjectsOnTile(e).find(e=>e.isBuilding()&&e.rules.refinery)}returnOreIfPossible(e){1===e.unitOrderTrait.getTasks().length&&e.unitOrderTrait.addTask(new ReturnOreTask(this.game))}getTargetLinesConfig(e){return{pathNodes:this.initialTarget?[{tile:this.initialTarget,onBridge:void 0}]:[]}}}class ReturnOreTask extends Task{constructor(e,t,i=!1,r=!1){super(),this.game=e,this.forceTarget=t,this.resetLastOreSite=i,this.explicitOrder=r,this.useChildTargetLines=!0,this.preventOpportunityFire=!1,this.rangeHelper=new RangeHelper(e.map.tileOccupation)}onStart(e){if(!e.isVehicle()||!e.harvesterTrait)throw new Error(`Unit ${e.name} is not a harvester.`);e.harvesterTrait.status=HarvesterStatus.MovingToRefinery,this.resetLastOreSite&&(e.harvesterTrait.lastOreSite=void 0)}onEnd(e){this.target?.isSpawned&&(this.target.dockTrait.undockUnit(e),this.target.dockTrait.unreserveDockForUnit(e)),e.harvesterTrait.status!==HarvesterStatus.LookingForRefinery&&(e.harvesterTrait.status=HarvesterStatus.Idle)}onTick(r){if(this.isCancelling())return!0;let s=r.harvesterTrait;if(s.status===HarvesterStatus.LookingForRefinery)return!0;if(s.status===HarvesterStatus.MovingToRefinery){if(!this.target||!this.isValidTargetRefinery(this.target,r)||r.tile!==this.findRefineryDockingTile(this.target)){var a=this.forceTarget??this.findClosestReachableRefinery(r);if(!a)return s.status=HarvesterStatus.LookingForRefinery,!0;this.target&&this.target!==a&&this.target.dockTrait.hasReservedDockForUnit(r)&&this.target.dockTrait.unreserveDockForUnit(r),this.target=a}let e=this.target.dockTrait.getFirstAvailableDockNumber(),t=!1;void 0===e&&(e=this.target.dockTrait.getFirstEmptyDockNumber(),void 0!==e&&(t=!this.target.dockTrait.hasReservedDockForUnit(r)));let i=this.findRefineryDockingTile(this.target);var n=this.rangeHelper.tileDistance(r,i);if(void 0===e||t||n>this.game.rules.general.harvesterTooFarDistance&&!this.explicitOrder){var o=this.findReachableQueueingTile(r);return o?(r.tile!==o&&this.children.push(r.rules.teleporter?new TeleportMoveToRefineryTask(this.game,i,o,()=>this.chronoMinerCanTeleport(r,i,this.target)):new MoveTask(this.game,o,!1),new CallbackTask(()=>{r.moveTrait.lastMoveResult===MoveResult.Fail?s.status=HarvesterStatus.LookingForRefinery:r.moveTrait.lastMoveResult===MoveResult.CloseEnough?this.children.push(new WaitMinutesTask(5/60)):r.moveTrait.lastMoveResult===MoveResult.Success&&this.children.push(new WaitMinutesTask(2/60))})),!1):!0}if(this.target.dockTrait.hasReservedDockForUnit(r)||this.target.dockTrait.reserveDockAt(r,e),void 0===this.reservedDockNumber&&(this.reservedDockNumber=this.target.dockTrait.getReservedDockForUnit(r)),r.tile!==i)return this.children.push(r.rules.teleporter?new TeleportMoveToRefineryTask(this.game,i,void 0,()=>this.chronoMinerCanTeleport(r,i,this.target)):new MoveTask(this.game,i,!1,{closeEnoughTiles:0,strictCloseEnough:!0}),new CallbackTask(()=>{r.moveTrait.lastMoveResult===MoveResult.Fail&&(s.status=HarvesterStatus.LookingForRefinery)})),!1;s.status=HarvesterStatus.Docking}if(!this.isValidTargetRefinery(this.target,r))return s.status=HarvesterStatus.MovingToRefinery,this.forceTarget=void 0,this.onTick(r);if(s.status===HarvesterStatus.Docking){if(270!==r.direction)return this.children.push(new TurnTask(270)),!1;this.target.dockTrait.dockUnitAt(r,this.reservedDockNumber),this.reservedDockNumber=void 0,s.status=HarvesterStatus.PreparingToUnload}if(s.status===HarvesterStatus.PreparingToUnload)return this.preventOpportunityFire=!0,this.children.push(new WaitMinutesTask(2/60)),s.status=HarvesterStatus.Unloading,!1;if(s.status!==HarvesterStatus.Unloading)return!1;var e=s.getBails().reduce((e,[t,i])=>e+i*this.game.rules.getTiberium(t).value,0),a=e,n=[...this.target.owner.buildings].filter(e=>e.rules.orePurifier&&(!e.poweredTrait||!this.target.owner.powerTrait?.isLowPower())).length,o=this.game.rules.general.purifierBonus;return a+=n*Math.floor(e*o),this.target.owner.credits+=a,this.target.owner.creditsGained+=a,s.empty(),1===r.unitOrderTrait.getTasks().length&&r.unitOrderTrait.addTask(new GatherOreTask(this.game)),!0}isValidTargetRefinery(e,t){return e.isSpawned&&this.game.areFriendly(e,t)&&!e.warpedOutTrait.isActive()}findClosestReachableRefinery(i){let r=this.rangeHelper;var e=i.zone===ZoneType.Air,t=i.rules.speedType,s=i.isInfantry();let a=!e&&this.game.map.terrain.getPassableSpeed(i.tile,t,s,i.onBridge)?this.game.map.terrain.getIslandIdMap(t,s):void 0,n=[...i.owner.buildings].filter(e=>e.rules.refinery&&e.dockTrait&&!e.warpedOutTrait.isActive()&&(e=>i.rules.teleporter||a?.get(e,!1)===a?.get(i.tile,i.onBridge))(this.findRefineryDockingTile(e))).sort((e,t)=>r.distance2(i,e)-r.distance2(i,t));t=n[0],s=n.find(e=>0<e.dockTrait.getAvailableDockCount());return!s||t&&r.tileDistance(i,s.centerTile)-r.tileDistance(i,t.centerTile)>this.game.rules.general.harvesterTooFarDistance?t:s}findReachableQueueingTile(t){if(this.target.art.queueingCell){var e=new Vector2(this.target.tile.rx,this.target.tile.ry).add(this.target.art.queueingCell),e=this.game.map.tiles.getByMapCoords(e.x,e.y);if(e&&this.isValidQueueingTile(e,t))return e}return new RadialTileFinder(this.game.map.tiles,this.game.map.mapBounds,this.target.tile,this.target.getFoundation(),1,1,e=>this.isValidQueueingTile(e,t)).getNextTile()}isValidQueueingTile(e,t){var i=t.zone===ZoneType.Air,r=t.rules.speedType,s=t.isInfantry();let a=!i&&this.game.map.terrain.getPassableSpeed(t.tile,r,s,t.onBridge)?this.game.map.terrain.getIslandIdMap(r,s):void 0;return i||a?.get(e,!1)===a?.get(t.tile,t.onBridge)&&Math.abs(e.z-this.target.tile.z)<2&&!e.onBridgeLandType}findRefineryDockingTile(e){e={x:e.tile.rx+e.getFoundation().width-1,y:e.tile.ry+Math.floor(e.getFoundation().height/2)};return this.game.map.tiles.getByMapCoords(e.x,e.y)}chronoMinerCanTeleport(e,t,i){let r=this.rangeHelper;t=r.tileDistance(e,t);return!(!this.forceTarget&&t>this.game.rules.general.chronoHarvTooFarDistance)&&(!(t<=1)&&(!!this.isValidTargetRefinery(i,e)&&!(0===i.dockTrait.getAvailableDockCount()&&!i.dockTrait.hasReservedDockForUnit(e))))}}(NotifyOrder=NotifyOrder||{}).onPush=Symbol(),function(e){e[e.Move=0]="Move",e[e.ForceMove=1]="ForceMove",e[e.Attack=2]="Attack",e[e.ForceAttack=3]="ForceAttack",e[e.AttackMove=4]="AttackMove",e[e.Guard=5]="Guard",e[e.GuardArea=6]="GuardArea",e[e.Capture=7]="Capture",e[e.Occupy=8]="Occupy",e[e.Deploy=9]="Deploy",e[e.DeploySelected=10]="DeploySelected",e[e.Stop=11]="Stop",e[e.Cheer=12]="Cheer",e[e.Dock=13]="Dock",e[e.Gather=14]="Gather",e[e.Repair=15]="Repair",e[e.Scatter=16]="Scatter",e[e.EnterTransport=17]="EnterTransport",e[e.PlaceBomb=18]="PlaceBomb"}(OrderType=OrderType||{}),function(e){e[e.Idle=0]="Idle",e[e.LookingForOreSite=1]="LookingForOreSite",e[e.MovingToOreSite=2]="MovingToOreSite",e[e.Harvesting=3]="Harvesting",e[e.LookingForRefinery=4]="LookingForRefinery",e[e.MovingToRefinery=5]="MovingToRefinery",e[e.Docking=6]="Docking",e[e.PreparingToUnload=7]="PreparingToUnload",e[e.Unloading=8]="Unloading"}(HarvesterStatus=HarvesterStatus||{});const CHECK_REFINERY_SECONDS=5,CHECK_EXTRA_REFINERY_SECONDS=25,CHECK_ORE_SITE_SECONDS=20;class HarvesterTrait{get ore(){return this._ore}get gems(){return this._gems}constructor(e){this.storage=e,this._ore=0,this._gems=0,this.bails=new Map,this.status=HarvesterStatus.Idle,this.lastGatherExplicit=!1,this.autoGatherOnNextIdle=!1,this.ticksSinceLastRefineryCheck=0,this.ticksSinceLastOreCheck=0}addBails(e,t){this.bails.set(e,(this.bails.get(e)??0)+t),e===TiberiumType.Gems?this._gems+=t:this._ore+=t}getBails(){return[...this.bails.entries()]}[NotifySpawn.onSpawn](e,t){e.owner.isCombatant()&&(t.afterTick(()=>{e.unitOrderTrait.addTask(new GatherOreTask(t))}),e.attackTrait?.increasePassiveScanCooldown(1))}[NotifyOwnerChange.onChange](e,t,i){(!t.isCombatant()&&e.owner.isCombatant()||i.alliances.areAllied(e.owner,t))&&i.afterTick(()=>{e.unitOrderTrait.addTask(new GatherOreTask(i))})}[NotifyTick_NotifyTick.onTick](e,t){this.status===HarvesterStatus.LookingForRefinery?this.ticksSinceLastRefineryCheck++>CHECK_REFINERY_SECONDS*GameSpeed.BASE_TICKS_PER_SECOND&&(this.ticksSinceLastRefineryCheck=0,e.unitOrderTrait.hasTasks()?this.ticksSinceLastRefineryCheck=-CHECK_EXTRA_REFINERY_SECONDS*GameSpeed.BASE_TICKS_PER_SECOND:[...e.owner.buildings].some(e=>e.rules.refinery)||this.lastGatherExplicit?e.unitOrderTrait.addTask(new ReturnOreTask(t)):this.status=HarvesterStatus.Idle):this.status===HarvesterStatus.LookingForOreSite?this.ticksSinceLastOreCheck++>CHECK_ORE_SITE_SECONDS*GameSpeed.BASE_TICKS_PER_SECOND&&(this.ticksSinceLastOreCheck=0,e.unitOrderTrait.hasTasks()||e.unitOrderTrait.addTask(new GatherOreTask(t))):this.status===HarvesterStatus.Idle&&this.autoGatherOnNextIdle&&e.unitOrderTrait.isIdle()&&e.tile.landType===LandType.Tiberium&&(this.autoGatherOnNextIdle=!1,e.unitOrderTrait.addTask(new GatherOreTask(t,e.tile,!0)))}[NotifyTeleport.onBeforeTeleport](e,t,i,r){!r&&e.owner.isCombatant()&&(this.status=HarvesterStatus.Idle,this.lastOreSite=void 0,i&&e.rules.teleporter&&t.afterTick(()=>{e.unitOrderTrait.addTask(new(this.isFull()?ReturnOreTask:GatherOreTask)(t))}))}[NotifyOrder.onPush](e,t){this.autoGatherOnNextIdle=[OrderType.AttackMove,OrderType.Move,OrderType.ForceMove,OrderType.Scatter].includes(t),[HarvesterStatus.LookingForRefinery,HarvesterStatus.LookingForOreSite].includes(this.status)&&(this.status=HarvesterStatus.Idle)}isFull(){return this.ore+this.gems>=this.storage}isEmpty(){return!this.ore&&!this.gems}empty(){this.bails.clear(),this._ore=this._gems=0}getHash(){return 100*this.ore+this.gems}debugGetState(){return{ore:this.ore,gems:this.gems}}}class LeaveTransportEvent{constructor(e){this.target=e,this.type=EventType.LeaveTransport}}class TransportTrait{constructor(e){this.obj=e,this.units=[],this.loadQueue=[]}unitFitsInside(e){return e.rules.size<=this.obj.rules.sizeLimit&&e.rules.size<=this.getAvailableCapacity()}getOccupiedCapacity(){return this.units.reduce((e,t)=>e+t.rules.size,0)}getMaxCapacity(){return this.obj.rules.passengers}getAvailableCapacity(){return this.getMaxCapacity()-this.getOccupiedCapacity()}addToLoadQueue(e){return this.loadQueue.push(e),this.loadQueue.length-1}unitIsFirstInLoadQueue(e){return this.loadQueue[0]===e}removeFromLoadQueue(e){e=this.loadQueue.indexOf(e);-1!==e&&this.loadQueue.splice(e,1)}[NotifyTick_NotifyTick.onTick](e,t){this.loadQueue=this.loadQueue.filter(e=>!e.isDestroyed&&!e.isCrashing)}[NotifyDestroy.onDestroy](e,t,i,r){var s=!!e.armedTrait?.deathWeapon,a=i?.weapon?.warhead.rules.parasite;if(r||s||e.zone===ZoneType.Air||a)for(var n of this.units)s&&n.armedTrait&&(n.armedTrait.deathWeapon=void 0),n.position.tileElevation=e.position.tileElevation,n.zone=e.zone,n.onBridge=e.onBridge,n.position.tile=e.tile,n.deathType=e.deathType,t.destroyObject(n,i,!0);else this.spawnSurvivors(t);this.units=[]}spawnSurvivors(e){var t=this.obj;if(this.units.length){for(var i of this.units)if(0<e.map.terrain.getPassableSpeed(t.tile,i.rules.speedType,i.isInfantry(),t.onBridge)){i.owner.addOwnedObject(i),i.position.tileElevation=t.onBridge?e.map.tileOccupation.getBridgeOnTile(t.tile).tileElevation:0,i.onBridge=t.onBridge,i.zone=e.map.getTileZone(t.tile,!t.onBridge),e.unlimboObject(i,t.tile),i.unitOrderTrait.addTask(new ScatterTask(e));const r=e.getUnitSelection();r.isSelected(t)&&r.addToSelection(i)}else i.position.tileElevation=t.position.tileElevation,i.zone=t.zone,i.onBridge=t.onBridge,i.position.tile=t.tile,i.zone===ZoneType.Water&&(i.deathType=DeathType.Sink),i.armedTrait?.deathWeapon&&(i.armedTrait.deathWeapon=void 0),e.destroyObject(i,{player:i.owner});e.events.dispatch(new LeaveTransportEvent(t))}}getHash(){return fnv32a(this.units.map(e=>e.getHash()))}debugGetState(){return this.units.map(e=>e.debugGetState())}dispose(){this.obj=void 0}}class GunnerTrait{[NotifyTick_NotifyTick.onTick](e){var t,i;!!e.transportTrait.units.length!==this.lastHadGunner&&(this.lastHadGunner=!!e.transportTrait.units.length,i=t=e.transportTrait.units[0]?.rules.ifvMode??0,(t=e.rules.turretIndexesByIfvMode.get(t)??0)<e.rules.turretCount&&(e.turretNo=t,e.armedTrait?.selectSpecialWeapon(i,e.veteranLevel===VeteranLevel.Elite)))}getUiNameForIfvMode(e,t){switch(e){case 0:return"tip:rocket";case 1:return"tip:repair";case 2:case 4:case 5:return"tip:machinegun";default:return t?"name:"+t.toLowerCase():void 0}}}(NotifyHeal=NotifyHeal||{}).onHeal=Symbol();const getSquidDamageTicks=()=>ROCKING_TICKS+2;class ParasiteableTrait{constructor(e){this.gameObject=e,this.beingBoarded=!1}infest(e,t){this.beingBoarded=!1,this.parasite=e,this.parasiteWeapon=t,e.rules.organic?this.damageTickCooldown=getSquidDamageTicks():this.damageTickCooldown=0,this.lastAttacker=void 0,this.lastExternalBaseDamage=void 0,this.lastExternalDamageTick=void 0,t.warhead.rules.paralyzes&&this.gameObject.moveTrait.setDisabled(!0)}isInfested(){return!(!this.parasite||this.parasite.isDestroyed)||this.beingBoarded}isParalyzed(){return!!this.parasiteWeapon?.warhead.rules.paralyzes}uninfest(){this.parasite&&(this.parasiteWeapon.warhead.rules.paralyzes&&this.gameObject.moveTrait.setDisabled(!1),this.parasite=void 0,this.parasiteWeapon=void 0)}getParasite(){return this.parasite}[NotifyTick_NotifyTick.onTick](r,s){if(this.parasite)if(this.parasite.isDestroyed)this.uninfest();else if(0<this.damageTickCooldown)this.damageTickCooldown--;else{let e=this.parasiteWeapon;this.damageTickCooldown=this.parasite.rules.organic?getSquidDamageTicks():e.getCooldownTicks();let t=e.rules.damage;this.parasite.veteranTrait&&(t*=this.parasite.veteranTrait.getVeteranDamageMultiplier());let i=e.warhead.computeDamage(t,r,s);this.canBeCulled(r,this.parasite,e,s)&&(i=r.healthTrait.getHitPoints()),e.warhead.inflictDamage(i,r,{player:this.parasite.owner,obj:this.parasite,weapon:e},s),r.isCrashing?(this.parasiteWeapon.expireCooldown(),this.evictOrDestroyParasite(r,s)):!r.isDestroyed&&r.isVehicle()&&r.zone!==ZoneType.Air&&e.warhead.rules.rocker&&r.applyRocking(90*(.5<=s.generateRandom()?1:-1),1)}}canBeCulled(e,t,i,r){if(!i.warhead.rules.culling)return!1;r=r.rules.audioVisual,r=t.veteranTrait?.isElite()?r.conditionYellow:r.conditionRed;return e.healthTrait.health<=100*r}[NotifyHeal.onHeal](e,t,i,r){!this.parasite||this.parasite.isDestroyed||r===e||e.isAircraft()&&r?.rules.unitReload||(!this.parasite.rules.organic||r?.rules.unitRepair?(this.parasite.deathType=DeathType.None,t.destroyObject(this.parasite,r?{player:r.owner,obj:r}:void 0),this.uninfest()):(r=this.parasite,this.evictOrDestroyParasite(e,t),this.stunParasite(r,t)))}[NotifyDamage.onDamage](e,t,i,r){r?.obj!==this.parasite&&(this.lastAttacker=r,this.lastExternalBaseDamage=r?.weapon?.rules.damage??i,this.lastExternalDamageTick=t.currentTick)}[NotifyAttack.onAttack](i,r,s){if(this.parasite&&!this.parasite.isDestroyed&&r?.weapon?.warhead.rules.sonic){var a=this.parasite;this.evictOrDestroyParasite(i,s),this.stunParasite(a,s);let e=r.weapon.warhead;e.canDamage(a,a.tile,a.zone)&&(i=e.computeDamage(r.weapon.rules.damage,a,s),e.inflictDamage(i,a,r,s));let t=r.obj?.unitOrderTrait.getCurrentTask();t instanceof AttackTask&&t.getWeapon().warhead.rules.sonic&&t.cancel()}}[NotifyDestroy.onDestroy](e,t,i,r){this.parasite&&!this.parasite.isDestroyed&&(r||this.shouldSupressParasite(t,this.parasite)?(this.parasite.deathType=DeathType.None,t.destroyObject(this.parasite,i,r),this.uninfest()):(this.parasiteWeapon.expireCooldown(),this.evictOrDestroyParasite(e,t)))}shouldSupressParasite(e,t){return!t.invulnerableTrait.isActive()&&this.lastExternalBaseDamage&&this.lastExternalBaseDamage>t.rules.suppressionThreshold&&e.currentTick-this.lastExternalDamageTick<2*(this.lastExternalBaseDamage-t.rules.suppressionThreshold)}[NotifyTeleport.onBeforeTeleport](e,t,i,r){i&&r&&this.parasite&&!this.parasite.isDestroyed&&(this.shouldSupressParasite(t,this.parasite)?(this.parasite.deathType=DeathType.None,t.destroyObject(this.parasite,this.lastAttacker),this.uninfest()):(this.parasiteWeapon.expireCooldown(),r=this.parasite,this.evictOrDestroyParasite(e,t,!0),r.isDestroyed||this.stunParasite(r,t)))}stunParasite(e,t){e.unitOrderTrait.addTaskToFront(new WaitMinutesTask(10/60).setCancellable(!1)),e.isVehicle()&&e.submergibleTrait&&(e.submergibleTrait.emerge(e,t),e.cloakableTrait?.uncloak(t),e.submergibleTrait.setCooldown(10*GameSpeed.BASE_TICKS_PER_SECOND))}evictOrDestroyParasite(r,s,a=!1){if(this.parasite&&!this.parasite.isDestroyed){if(s.map.terrain.getPassableSpeed(r.tile,this.parasite.rules.speedType,this.parasite.isInfantry(),r.onBridge)||s.map.getObjectsOnTile(r.tile).find(e=>e.isBuilding())){let t=r.tile,i=r.onBridge;if(!a&&!r.isDestroyed||this.parasite.rules.organic){let e=new RadialTileFinder(s.map.tiles,s.map.mapBounds,t,{width:1,height:1},1,1,e=>0<s.map.terrain.getPassableSpeed(e,this.parasite.rules.speedType,this.parasite.isInfantry(),i)&&!s.map.terrain.findObstacles({tile:e,onBridge:i},this.parasite).length);a=e.getNextTile();if(!a)return this.parasite.deathType=DeathType.None,s.destroyObject(this.parasite,{player:r.owner,obj:r}),void this.uninfest();t=a}this.parasite.onBridge=i,this.parasite.position.subCell=this.parasite.isInfantry()?r.position.subCell:0,this.parasite.zone=s.map.getTileZone(t,!i),this.parasite.position.tileElevation=i?s.map.tileOccupation.getBridgeOnTile(t).tileElevation:0,this.parasite.resetGuardModeToIdle(),s.unlimboObject(this.parasite,t,!0)}else this.parasite.deathType=DeathType.None,s.destroyObject(this.parasite,{player:r.owner,obj:r});this.uninfest()}}destroyParasite(e,t){this.parasite&&(this.parasite.deathType=DeathType.None,t.destroyObject(this.parasite,e),this.uninfest())}dispose(){this.gameObject=void 0}}class ShipSubmergeChangeEvent{constructor(e){this.target=e,this.type=EventType.ShipSubmergeChange}}const SUBMERGE_PENALTY_SECONDS=5;class SubmergibleTrait{constructor(){this.isActive=!1}isSubmerged(){return this.isActive}setCooldown(e){this.cooldownTicks=e}[NotifyTick_NotifyTick.onTick](e,t){this.isActive||e.parasiteableTrait?.isInfested()||(e.attackTrait&&e.attackTrait.attackState!==AttackState.Idle&&!e.moveTrait.isMoving()?this.cooldownTicks=Math.max(this.cooldownTicks??0,SUBMERGE_PENALTY_SECONDS*GameSpeed.BASE_TICKS_PER_SECOND):this.cooldownTicks??(this.cooldownTicks=Math.floor(60*t.rules.general.cloakDelay*GameSpeed.BASE_TICKS_PER_SECOND)),0<this.cooldownTicks&&this.cooldownTicks--,this.cooldownTicks<=0&&(this.isActive=!0,t.events.dispatch(new ShipSubmergeChangeEvent(e))))}[NotifyDamage.onDamage](e,t){this.emerge(e,t)}emerge(e,t){this.isActive&&(this.isActive=!1,this.cooldownTicks=void 0,t.events.dispatch(new ShipSubmergeChangeEvent(e)))}}class HoverBobTrait{constructor(){this.prevHoverBobLeptons=0,this.spawnTick=0}[NotifySpawn.onSpawn](e,t){this.setBaseElevation(e,t),this.spawnTick=t.currentTick}[NotifyTileChange_NotifyTileChange.onTileChange](e,t,i,r){r&&(this.prevHoverBobLeptons=0,this.setBaseElevation(e,t))}setBaseElevation(e,t){e.position.tileElevation=(e.onBridge?t.map.tileOccupation.getBridgeOnTile(e.tile)?.tileElevation??0:0)+Coords.worldToTileHeight(t.rules.general.hover.height)}[NotifyTick_NotifyTick.onTick](e,t){var i=this.computeHoverBobLeptons(t.currentTick,t.rules.general.hover),t=i-this.prevHoverBobLeptons;this.prevHoverBobLeptons=i;i=Coords.tileHeightToWorld(e.position.tileElevation);e.position.tileElevation=Coords.worldToTileHeight(i+t)}computeHoverBobLeptons(e,t){e=(e-this.spawnTick)/GameSpeed.BASE_TICKS_PER_SECOND/(60*t.bob);return.1*t.height*GameMath.sin(2*e*Math.PI)}}class TilterTrait{constructor(){this.tilt={pitch:0,yaw:0}}[NotifySpawn.onSpawn](e){this.tilt=this.computeTilt(e.tile.rampType)}[NotifyTileChange_NotifyTileChange.onTileChange](e){this.tilt=this.computeTilt(e.tile.rampType)}computeTilt(e){let t,i;return 0===e||17<=e?t=i=0:i=e<=4?(t=25,-90*e):(t=25,225-(e-1)%4*90),{pitch:t,yaw:i}}}const ROCKING_TICKS=34;class Vehicle_Vehicle extends Techno_Techno{get isMoving(){return this.moveTrait.isMoving()}static factory(e,t,i,r,s){let a=new this(e,t,i);return a.isSinker=!t.underwater&&(t.weight>=r.general.shipSinkingWeight||!t.naval),a.moveTrait=new MoveTrait(a,s),a.traits.add(a.moveTrait),t.crashable&&(a.crashableTrait=new CrashableTrait(a),a.traits.add(a.crashableTrait)),t.crewed&&(a.crewedTrait=new CrewedTrait,a.traits.add(a.crewedTrait)),t.harvester&&(a.harvesterTrait=new HarvesterTrait(t.storage),a.traits.add(a.harvesterTrait)),t.passengers&&(a.transportTrait=new TransportTrait(a),a.traits.add(a.transportTrait),t.gunner&&(a.gunnerTrait=new GunnerTrait,a.traits.add(a.gunnerTrait))),t.turret&&(a.turretTrait=new TurretTrait,a.traits.add(a.turretTrait)),t.consideredAircraft&&!t.landable||a.traits.add(new DockableTrait),t.parasiteable&&(a.parasiteableTrait=new ParasiteableTrait(a),a.traits.add(a.parasiteableTrait)),t.naval&&t.underwater&&(a.submergibleTrait=new SubmergibleTrait,a.traits.add(a.submergibleTrait)),t.locomotor===LocomotorType.Hover&&a.traits.add(new HoverBobTrait),[LocomotorType.Vehicle,LocomotorType.Chrono].includes(t.locomotor)&&i.isVoxel&&(a.tilterTrait=new TilterTrait,a.traits.add(a.tilterTrait)),a}constructor(e,t,i){super(ObjectType.Vehicle,e,t,i),this.direction=0,this.spinVelocity=0,this.crateBonuses=new CrateBonuses,this.turretNo=0,this.onBridge=!1,this.isSinker=!1,this.isFiring=!1,this.zone=t.naval?ZoneType.Water:ZoneType.Ground}isUnit(){return!0}isVehicle(){return!0}getUiName(){if(this.gunnerTrait){var e=this.armedTrait.getSpecialWeaponIndex(),t=this.gunnerTrait.getUiNameForIfvMode(e,this.transportTrait?.units[0]?.name),e="name:"+this.name;return t?`{${t}} {${e}}`:e}return super.getUiName()}update(e){this.rocking&&(this.rocking.ticksLeft--,this.rocking.ticksLeft||(this.rocking=void 0)),super.update(e)}applyRocking(e,t){this.rules.consideredAircraft||(this.rocking={ticksLeft:this.rocking?.ticksLeft??ROCKING_TICKS,facing:e,factor:t})}}class AirportBoundTrait{constructor(e){this.airportNames=e}findAvailableAirport(e){return[...e.owner.buildings].find(e=>e.dockTrait&&this.airportNames.includes(e.name)&&0<e.dockTrait.getAvailableDockCount())}}class SpawnLinkTrait{setParent(e){this.parent=e}getParent(){return this.parent}[NotifyTick_NotifyTick.onTick](r,s){if(this.parent&&r.attackTrait&&r.primaryWeapon){let e=this.parent.attackTrait?.currentTarget,t=r.unitOrderTrait.getCurrentTask(),i=new RangeHelper(s.map.tileOccupation);var a=this.parent.armedTrait?.getWeapons().find(e=>e.rules.spawner);r.ammo&&!(e&&r.attackTrait.currentTarget?e.equals(r.attackTrait.currentTarget):e===r.attackTrait.currentTarget||!e&&this.parent.isUnit()&&(this.parent.unitOrderTrait.getCurrentTask()instanceof MoveTask||this.parent.unitOrderTrait.getCurrentTask()instanceof AttackTask))&&(!e||a&&i.isInWeaponRange(this.parent,e.obj??e.tile,a,s.rules))?e&&r.primaryWeapon.targeting.canTarget(e.obj,e.tile,s,!0,!1)?!t||t instanceof MoveTask?(r.unitOrderTrait.cancelAllTasks(),r.unitOrderTrait.addTask(r.attackTrait.createAttackTask(s,e.obj,e.tile,r.primaryWeapon,{force:!0}))):r.attackTrait.attackState!==AttackState.Idle&&t.requestTargetUpdate(e):t?t instanceof MoveTask||t.cancel():this.tryMoveToParent(r,this.parent,s):this.tryMoveToParent(r,this.parent,s)}}tryMoveToParent(t,i,r){if(t.tile!==i.tile){let e=t.unitOrderTrait.getCurrentTask();e?e instanceof MoveTask&&e.updateTarget(i.tile,!!i.isUnit()&&i.onBridge):t.unitOrderTrait.addTask(new MoveTask(r,i.tile,!!i.isUnit()&&i.onBridge,{closeEnoughTiles:0,strictCloseEnough:!0}))}}}class MissileSpawnTrait{setWarhead(e){return this.warhead=e,this}setDamage(e){return this.damage=e,this}setLauncher(e){return this.launcher=e,this}[NotifyDestroy.onDestroy](e,t){this.warhead&&this.damage&&this.launcher&&this.warhead.detonate(t,this.damage,e.tile,e.tileElevation,e.position.worldPosition,e.zone,CollisionType.None,t.createTarget(void 0,e.tile),{player:e.owner,obj:this.launcher,weapon:void 0})}dispose(){this.launcher=void 0}}class Aircraft_Aircraft extends Techno_Techno{get direction(){return this.yaw}set direction(e){this.yaw=e}get isMoving(){return this.moveTrait.isMoving()}static factory(e,t,i,r,s){let a=new this(e,t,i);return a.rules.airportBound&&a.rules.dock.length&&(a.airportBoundTrait=new AirportBoundTrait(a.rules.dock),a.traits.add(a.airportBoundTrait)),a.rules.missileSpawn||(a.crashableTrait=new CrashableTrait(a),a.traits.add(a.crashableTrait)),a.rules.spawned&&(a.rules.missileSpawn?(a.missileSpawnTrait=new MissileSpawnTrait,a.traits.add(a.missileSpawnTrait)):(a.spawnLinkTrait=new SpawnLinkTrait,a.traits.add(a.spawnLinkTrait))),a.moveTrait=new MoveTrait(a,s),a.traits.add(a.moveTrait),t.dock.length&&a.traits.add(new DockableTrait),t.landable&&e!==r.general.paradrop.paradropPlane||a.traits.add(new UnlandableTrait),t.parasiteable&&(a.parasiteableTrait=new ParasiteableTrait(a),a.traits.add(a.parasiteableTrait)),a}constructor(e,t,i){super(ObjectType.Aircraft,e,t,i),this.pitch=0,this.yaw=0,this.roll=0,this.onBridge=!1,this.zone=ZoneType.Ground,this.crateBonuses=new CrateBonuses}isUnit(){return!0}isAircraft(){return!0}}class UnitOrderTrait{constructor(e){this.gameObject=e,this.orders=[],this.queuedOrders=new Set,this.tasks=[],this.taskRunner=new TaskRunner}[NotifyTick_NotifyTick.onTick](i,e){if(i.isSpawned){var r=this.hasTasks(),t=this.tasks.find(e=>!e.isCancelling());if(r&&this.taskRunner.tick(this.tasks,i),i.isSpawned){var s,a=this.orders.length;if(a&&(!r||!t)){let e,t=!1;for(;e=this.orders[0];){if(e.isValid()&&e.isAllowed()&&((s=e.process())&&(this.queuedOrders.has(e)&&(this.tasks.push(new WaitTicksTask(5)),this.tasks.push(new CallbackTask(()=>{i.resetGuardModeToIdle()}))),this.tasks.push(...s),r||this.taskRunner.tick(this.tasks,i)),t=!0),this.orders.shift(),this.queuedOrders.delete(e),!i.isSpawned)return;if(this.waypointPath&&(this.currentWaypoint?(this.cleanupWaypoint(this.currentWaypoint,this.waypointPath),this.currentWaypoint=this.currentWaypoint?.next):this.currentWaypoint=this.waypointPath.waypoints[0],this.currentWaypoint||this.cleanupWaypointPath()),t)break}}!a&&!r&&this.waypointPath&&this.currentWaypoint&&(this.cleanupWaypoint(this.currentWaypoint,this.waypointPath),this.cleanupWaypointPath());let e=t;for(;e?.useChildTargetLines;){var n=e.children.find(e=>!e.isCancelling());if(!n)break;e=n}this.targetLinesTask!==e&&(this.targetLinesTask=e,this.targetLinesConfig=e?.getTargetLinesConfig(this.gameObject))}}}[NotifyOwnerChange.onChange](){this.clearOrders(),this.cancelAllTasks()}[NotifyTeleport.onBeforeTeleport](e,t,i,r){i&&!r&&(this.clearOrders(),this.tasks.length=0)}addOrder(t,e=!1){!1!==t.onAdd(this.tasks,e)?(e||(this.clearOrders(),this.tasks=this.tasks.filter(e=>e.status!==TaskStatus.NotStarted),this.tasks.forEach(e=>e.cancel())),this.orders.push(t),e&&this.queuedOrders.add(t),this.gameObject.traits.filter(NotifyOrder).forEach(e=>{e[NotifyOrder.onPush](this.gameObject,t.orderType)})):this.targetLinesTask=void 0}clearOrders(){this.orders.length=0,this.queuedOrders.clear(),this.currentWaypoint&&this.waypointPath&&this.cleanupWaypoint(this.currentWaypoint,this.waypointPath),this.cleanupWaypointPath(),this.gameObject.resetGuardModeToIdle()}unmarkNextQueuedOrder(){this.orders.length&&this.queuedOrders.delete(this.orders[0])}hasTasks(){return!!this.tasks.length}isIdle(){return!this.orders.length&&!this.tasks.length}getCurrentTask(){return this.tasks[0]}cancelAllTasks(){this.tasks.forEach(e=>e.cancel())}addTask(e){this.tasks.push(e)}addTasks(...e){e.forEach(e=>this.addTask(e))}addTaskToFront(e){this.tasks.unshift(e)}addTaskNext(e){this.tasks.splice(1,0,e)}getTasks(){return[...this.tasks]}dispose(){this.clearOrders(),this.tasks.length=0,this.gameObject=void 0}cleanupWaypointPath(){this.waypointPath&&(this.waypointPath.units.splice(this.waypointPath.units.indexOf(this.gameObject),1),this.waypointPath.units.length||(this.waypointPath.waypoints.forEach(e=>e.next=void 0),this.waypointPath.waypoints.length=0),this.waypointPath=void 0),this.currentWaypoint=void 0}cleanupWaypoint(t,e){if(!e.units.find(e=>e!==this.gameObject&&(e.unitOrderTrait.currentWaypoint??e.unitOrderTrait.waypointPath?.waypoints[0])===t)&&!e.waypoints.find(e=>e.next===t)){var i=e.waypoints.indexOf(t);if(-1===i)throw new Error("Given waypoint not found in waypoint path");e.waypoints.splice(i,1)}}}const rampHeights=[[0,0,0,0],[0,0,1,1],[1,0,0,1],[1,1,0,0],[0,1,1,0],[0,0,0,1],[1,0,0,0],[0,1,0,0],[0,0,1,0],[1,0,1,1],[1,1,0,1],[1,1,1,0],[0,1,1,1],[1,0,1,2],[2,1,0,1],[1,2,1,0],[0,1,2,1],[1,0,1,0],[0,1,0,1],[1,0,1,0],[0,1,0,1]];class ObjectPosition{get onPositionChange(){return this._onPositionChange.asEvent()}get worldPosition(){return this._worldPosition}get tile(){return this._tile}set tile(e){var t=!!this._tile&&e!==this._tile;(this._tile=e)&&(this.updateWorldPosition(e,this._tileOffset),this._onPositionChange.dispatch(this,{tileChanged:t}))}get tileElevation(){return void 0===this._tileElevation?(void 0===this._computedTileElevation&&(this._computedTileElevation=this.computeTileElevationFromWorldPos()),this._computedTileElevation):this._tileElevation}set tileElevation(e){this._absoluteElevation=void 0,this._tileElevation=e,this._tile&&(this.updateWorldPosition(this._tile,this._tileOffset),this._onPositionChange.dispatch(this,{tileChanged:!1}))}get subCell(){if(!this._tileOffset.x&&!this._tileOffset.y)return 0;var e=Math.sign(this._tileOffset.x/Coords.LEPTONS_PER_TILE-.5),t=Math.sign(this._tileOffset.y/Coords.LEPTONS_PER_TILE-.5);return e&&t?t+1+(e+1)/2+1:0}set subCell(e){this._tileOffset=this.computeSubCellOffset(e),this.desiredSubCell=e,this._tile&&(this.updateWorldPosition(this._tile,this._tileOffset),this._onPositionChange.dispatch(this,{tileChanged:!1}))}constructor(e,t){this.tiles=e,this.tileOccupation=t,this._worldPosition=new Vector3_Vector3,this._tileOffset=new Vector2,this._centerOffset=new Vector2,this.desiredSubCell=0,this._tileElevation=0,this._onPositionChange=new EventDispatcher}getTileOffset(){return this._tileOffset.clone()}setTileOffset(e){this._tileOffset.copy(e),this._tile&&(this.updateWorldPosition(this._tile,this._tileOffset),this._onPositionChange.dispatch(this,{tileChanged:!1}))}setCenterOffset(e){this._centerOffset.copy(e),this._tile&&(this.updateWorldPosition(this._tile,this._tileOffset),this._onPositionChange.dispatch(this,{tileChanged:!1}))}getMapPosition(){if(this._tile)return new Vector2(this._tile.rx*Coords.LEPTONS_PER_TILE+this._tileOffset.x+this._centerOffset.x,this._tile.ry*Coords.LEPTONS_PER_TILE+this._tileOffset.y+this._centerOffset.y)}getBridgeBelow(){return this._tile?.onBridgeLandType?this.tileOccupation.getBridgeOnTile(this._tile):void 0}moveToTileCell(e,t=0){if(!this._tile)throw new Error("Tile is not set");var i=e!==this._tile;this._tile=e,this._tileOffset=this.computeSubCellOffset(t),this.desiredSubCell=t,this.updateWorldPosition(e,this._tileOffset),this._onPositionChange.dispatch(this,{tileChanged:i})}moveToTileCoords(e,t,i=!1){var r=Math.floor(e),s=Math.floor(t),a=!this._tile||this._tile.rx!==r||this._tile.ry!==s;if(a){let e=this.tiles.getByMapCoords(r,s);if(!e){if(!i)throw new RangeError(`Attempted move to a non-existent tile: [${r},${s}]`);e=this.tiles.getPlaceholderTile(r,s)}this._tile=e}this._tileOffset.set((e-r)*Coords.LEPTONS_PER_TILE,(t-s)*Coords.LEPTONS_PER_TILE),this.updateWorldPosition(this._tile,this._tileOffset),this._onPositionChange.dispatch(this,{tileChanged:a})}moveToLeptons(e,t=!1){this.moveToTileCoords(e.x/Coords.LEPTONS_PER_TILE,e.y/Coords.LEPTONS_PER_TILE,t)}moveByLeptons(e,t,i=!1){if(!this._tile)throw new Error("Tile is not set");this.moveToTileCoords(this._tile.rx+(this._tileOffset.x+e)/Coords.LEPTONS_PER_TILE,this._tile.ry+(this._tileOffset.y+t)/Coords.LEPTONS_PER_TILE,i)}moveByLeptons3(e,t=!1){var i=this._worldPosition.y;this.moveByLeptons(e.x,e.z,t),this.setAbsoluteElevationWorld(i+e.y)}setAbsoluteElevationWorld(e){this._absoluteElevation=e,this._tileElevation=void 0,this._tile&&(this.updateWorldPosition(this._tile,this._tileOffset),this._onPositionChange.dispatch(this,{tileChanged:!1}))}computeSubCellOffset(e){let t={width:0,height:0};var i;e&&(i=(e-1)%2*2-1,r=2*Math.floor((e-1)/2)-1,t={width:i*Coords.LEPTONS_PER_TILE/4,height:r*Coords.LEPTONS_PER_TILE/4});var r=Coords.LEPTONS_PER_TILE/2;return new Vector2(r+t.width,r+t.height)}interpolateRampHeight(e,t,i){var r=rampHeights[i],s=r[1],i=r[0];return s*(1-e)*(1-t)+r[2]*e*(1-t)+i*(1-e)*t+r[3]*e*t}updateWorldPosition(t,i){var e=i.x+this._centerOffset.x,r=i.y+this._centerOffset.y,s=e/Coords.LEPTONS_PER_TILE,i=r/Coords.LEPTONS_PER_TILE;let a;if(void 0!==this._tileElevation){let e=0;0!==t.rampType&&(e=this.interpolateRampHeight(s,i,t.rampType)),a=Coords.tileHeightToWorld(t.z+e+this._tileElevation)}else a=this._absoluteElevation;this._worldPosition.set(t.rx*Coords.LEPTONS_PER_TILE+e,a,t.ry*Coords.LEPTONS_PER_TILE+r),void 0===this._tileElevation&&(this._computedTileElevation=this.computeTileElevationFromWorldPos())}computeTileElevationFromWorldPos(){if(!this._tile)return 0;var e=roundToDecimals(Coords.worldToTileHeight(this._worldPosition.y),14),t=(this._tileOffset.x+this._centerOffset.x)/Coords.LEPTONS_PER_TILE,i=(this._tileOffset.y+this._centerOffset.y)/Coords.LEPTONS_PER_TILE;let r=0;return 0!==this._tile.rampType&&(r=this.interpolateRampHeight(t,i,this._tile.rampType)),e-this._tile.z-r}clone(){let e=new ObjectPosition(this.tiles,this.tileOccupation);return e._worldPosition=this._worldPosition.clone(),e._tile=this._tile,e._tileOffset=this._tileOffset.clone(),e._centerOffset=this._centerOffset.clone(),e._tileElevation=this._tileElevation,e._absoluteElevation=this._absoluteElevation,e._computedTileElevation=this._computedTileElevation,e}}const AIR_DETONATION_Z_THRESH=1.5,WALL_HEIGHT=2,UNIT_HEIGHT=1.1;class CollisionHelper{constructor(e){this.tileOccupation=e}checkCollisions(e,t,i){var r,s=e.tile;let a,n,o;for(r of this.tileOccupation.getObjectsOnTile(s))r.isOverlay()&&r.isBridge()&&(a=r),r.isOverlay()&&r.wallTrait&&(o=r),r.isTechno()&&!r.isDestroyed&&(n=r);if(i.walls){if(e.tileElevation<=WALL_HEIGHT&&s.landType===LandType.Wall)return{type:CollisionType.Wall,target:o};if(i.units&&n?.tile===s&&(!n.isUnit()||n.zone===ZoneType.Ground)&&e.tileElevation<=UNIT_HEIGHT&&i.units(n.owner))return{type:CollisionType.Wall,target:n}}if(i.shore&&s.landType!==LandType.Water)return{type:CollisionType.Shore};if(i.ground&&e.tileElevation<0)return{type:CollisionType.Ground};var l=e.tileElevation+s.z,h=t.tileElevation+t.tile.z;if(a?.isHighBridge()){var c=a.tile.z+a.tileElevation;if(c<h&&l<=c||h<c&&c-1<=l)return h<c?{type:CollisionType.UnderBridge,target:a}:{type:CollisionType.OnBridge,target:a}}else if(a?.isLowBridge()&&i.shore)return{type:CollisionType.UnderBridge,target:a};if(i.cliffs){t=s.z-t.tile.z;if(e.tileElevation<0&&4<=t)return{type:CollisionType.Cliff}}return{type:CollisionType.None}}computeDetonationZone(e,t,i){let r=this.tileOccupation.getBridgeOnTile(e);return i===CollisionType.None&&t>AIR_DETONATION_Z_THRESH+(r?.tileElevation??0)?ZoneType.Air:r&&t>AIR_DETONATION_Z_THRESH||e.terrainType!==TerrainType.Water||r?.isLowBridge()?ZoneType.Ground:ZoneType.Water}}const CRUISING_ELEVATION_TILE_THRESH=2,CRUISING_ELEVATION_BASE=2,CRUISING_ELEVATION_TILES=3,HOMING_ELEVATION_Z_SPEED=.25,LIMBO_TELEPORT_TICKS=10,MAX_OVERSHOOT_TILES=2;!function(e){e[e.Travel=0]="Travel",e[e.Impact=1]="Impact",e[e.Detonation=2]="Detonation"}(ProjectileState=ProjectileState||{});class Projectile extends GameObject{get fromObject(){return this._fromObject}set fromObject(e){(this._fromObject=e)&&e.veteranTrait&&!e.isDestroyed&&(this.veteranDamageMult=e.veteranTrait.getVeteranDamageMultiplier())}get rot(){return this.fromWeapon.rules.isSonic?ObjectRules.iniRotToDegsPerTick(this.iniRot):this.rules.rot}get iniRot(){return this.fromWeapon.rules.isSonic?10:this.rules.iniRot}static factory(e,t,i,r){return new this(e,t,i,r)}constructor(e,t,i,r){super(ObjectType.Projectile,e,t,i),this.tileOccupation=r,this.state=ProjectileState.Travel,this.detonationTimer=0,this.collisionType=CollisionType.None,this.direction=0,this.zone=ZoneType.Air,this.isShrapnel=!1,this.isNuke=!1,this.baseDamageMultiplier=1,this.veteranDamageMult=1,this.snapToTarget=!1,this.targetLockLost=!1,this.limboTravelTicks=0,this.homingTravelDistance=0,this.homingTravelTicks=0,this.velocity=new Vector3_Vector3,this.sonicVisitedObjects=new Map,this.collisionHelper=new CollisionHelper(r)}onSpawn(a){var e;if(super.onSpawn(a),this.initialSelfPosition=this.position.worldPosition.clone(),!this.target.obj||this.fromWeapon.type===WeaponType.DeathWeapon||this.fromWeapon.rules.limboLaunch||!this.isHoming()&&this.fromWeapon.speed===Number.POSITIVE_INFINITY||this.rules.inaccurate||this.rules.arcing||this.rules.flakScatter||0<(e=this.computeBaseDamage(a))&&(e=this.fromWeapon.warhead.computeDamage(e,this.target.obj,a),this.target.obj.healthTrait?.projectDamage(e)),a.afterTick(()=>{let e=new RangeHelper(this.tileOccupation);var t=e.distance2(this.target.getWorldCoords(),this)/Coords.LEPTONS_PER_TILE;this.initialTileDistToTarget=t,this.maxSpeed=this.computeMaxSpeed(this.fromWeapon.speed,t,a.rules.audioVisual.gravity)}),this.isHoming()){if(1===this.iniRot&&(this.homingMoveDir=this.target.getWorldCoords().clone().sub(this.position.worldPosition)),this.fromObject?.isAircraft()&&this.rules.isAntiGround&&!this.rules.isAntiAir){let e=this.target.obj;!e?.isVehicle()||e.isDestroyed||e.veteranLevel!==VeteranLevel.Elite||e.unitOrderTrait.hasTasks()||e.unitOrderTrait.addTask(new ScatterTask(a))}}else if(this.rules.vertical){let e=this.position.clone();e.tileElevation=this.fromWeapon.warhead.rules.nukeMaker?Coords.worldToTileHeight(this.fromWeapon.projectileRules.detonationAltitude):0,this.aimPoint=e.worldPosition.clone()}else{let s=this.target.getWorldCoords().clone();a.afterTick(()=>{let e=this.target.getWorldCoords().clone().sub(s);var t=e.length()>Coords.LEPTONS_PER_TILE;let i=t?s:this.target.obj?.isUnit()&&this.target.obj.moveTrait.velocity.length()&&isFinite(this.maxSpeed)?this.computeAimPointVersusMovingTarget(this.target.obj,this.maxSpeed,this.position.worldPosition,a.map):this.target.getWorldCoords().clone();this.aimPoint=i,this.snapToTarget=!t&&isFinite(this.maxSpeed)&&!this.fromWeapon.warhead.rules.sonic,(this.rules.inaccurate||this.rules.flakScatter)&&(this.adjustAimForBallisticScatter(a,i),this.snapToTarget=!1),!t&&this.rules.arcing&&(this.rules.inaccurate?(this.overshootTiles=this.calculateInaccurateBallisticOvershoot(a),this.snapToTarget=!1):this.target.obj?.isVehicle()&&this.target.obj.moveTrait.isMoving()&&(this.overshootTiles=this.calculateBallisticOvershootVsMoving(a,this.target.obj),this.overshootTiles&&(this.snapToTarget=!1)));let r=i.clone().sub(this.position.worldPosition);r.length()<this.fromWeapon.speed&&this.update(a)})}}adjustAimForBallisticScatter(e,t){let i=e.rules.combatDamage.ballisticScatter,r;r=this.rules.flakScatter?(this.rules.inviso&&(i*=2),e.generateRandom()*i):i/2+e.generateRandom()*(i/2);let s=r*Coords.LEPTONS_PER_TILE;this.rules.flakScatter&&(n=t.clone().sub(this.initialSelfPosition).length(),s*=n/(this.fromWeapon.range*Coords.LEPTONS_PER_TILE));var a=rotateVec2(new Vector2(s,0),e.generateRandomInt(0,360)),n=Coords.vecWorldToGround(t).add(a).multiplyScalar(1/Coords.LEPTONS_PER_TILE).floor();e.map.tiles.getByMapCoords(n.x,n.y)&&t.add(new Vector3_Vector3(a.x,0,a.y))}calculateBallisticOvershootVsMoving(e,t){let i=this.target.getWorldCoords().clone().sub(this.initialSelfPosition);var r=angleDegBetweenVec2(Coords.vecWorldToGround(i),Coords.vecWorldToGround(t.moveTrait.velocity)),t=(90<r?180-r:r)/90,r=i.length()/Coords.LEPTONS_PER_TILE,t=t*r/5;return e.generateRandom()<=t?Math.min(1,r/5)*MAX_OVERSHOOT_TILES:0}calculateInaccurateBallisticOvershoot(e){return e.generateRandom()<=.5?MAX_OVERSHOOT_TILES:0}update(o){if(void 0!==this.maxSpeed)if(super.update(o),this.state!==ProjectileState.Impact){var s=this.velocity.clone(),l=this.position.clone();if(this.velocity.set(0,0,0),this.fromWeapon.rules.limboLaunch){if(!this.fromObject)throw new Error("Limbo launch projectile must be fired from a unit");if(this.fromObject.isDestroyed)return void o.destroyObject(this)}var h=this.updateSpeed(this.maxSpeed);this.speed=h;let n=this.target.getWorldCoords();if(this.lastTargetLockPosition&&(this.targetLockLost||n.clone().sub(this.lastTargetLockPosition).length()>=Coords.LEPTONS_PER_TILE)?(n=this.lastTargetLockPosition,this.targetLockLost=!0):this.lastTargetLockPosition=n.clone(),this.isHoming()){if(this.target.obj?.isUnit()&&(this.target.obj.isDestroyed||this.target.obj.isCrashing||!this.target.obj.isSpawned)&&(this.fromWeapon.rules.limboLaunch||this.homingTravelDistance>=2*Coords.LEPTONS_PER_TILE))return void this.detonate(o);if(this.homingMoveDir||(d=FacingUtil.toMapCoords(this.direction),this.homingMoveDir=new Vector3_Vector3(d.x,0,d.y),this.fromObject?.isAircraft()&&(this.homingMoveDir.y=-9999999,this.homingMoveDir.normalize())),this.fromWeapon.rules.limboLaunch){if(!this.targetLockLost){if(this.limboTravelTicks>LIMBO_TELEPORT_TICKS)return this.position.moveToLeptons(this.target.obj.position.getMapPosition()),this.position.tileElevation=this.target.obj.position.tileElevation,void this.detonate(o);this.limboTravelTicks++}}else if(!this.isInHomingRange(n,o))return void this.detonate(o);let e=new RangeHelper(this.tileOccupation);var c=Math.floor(e.distance2(n,this)/Coords.LEPTONS_PER_TILE),d=c>CRUISING_ELEVATION_TILE_THRESH&&1<this.iniRot;let t=n.clone().sub(this.position.worldPosition),i=0;this.homingTravelTicks<this.rules.courseLockDuration||(d?(rotateVec3Towards(this.homingMoveDir,new Vector3_Vector3(t.x,this.homingMoveDir.y,t.z),this.rot),this.rules.level||(c=clamp(Math.floor(this.initialTileDistToTarget)-1,0,CRUISING_ELEVATION_BASE)+clamp(c-CRUISING_ELEVATION_TILE_THRESH,0,CRUISING_ELEVATION_TILES),u=this.tileOccupation.getBridgeOnTile(this.tile)?.tileElevation??0,(u=c-(this.position.tileElevation-u))&&(p=HOMING_ELEVATION_Z_SPEED+6/this.iniRot*.1,i=Coords.tileHeightToWorld(Math.sign(u)*Math.min(Math.abs(u),p))))):rotateVec3Towards(this.homingMoveDir,t,this.rot)),this.direction=FacingUtil.fromMapCoords(new Vector2(this.homingMoveDir.x,this.homingMoveDir.z));var u=t.length(),p=Math.min(u,h);this.homingTravelDistance+=p,this.homingTravelTicks++;let r=!1,s=CollisionType.None,a;if(u>=Coords.LEPTONS_PER_TILE/4){let e=this.homingMoveDir.clone().setLength(p);i&&(e.y+=i),p===h&&this.velocity.copy(e);var g=e.clone().add(this.position.worldPosition);o.map.mapBounds.isWithinHardBounds(g)?this.position.moveByLeptons3(e):r=!0;var m=this.checkObstacles(l,o);if(s=m.type,a=m.target,s)r=!0;else{let e=n.clone().sub(this.position.worldPosition);var y=e.length();u<y&&y<2*Coords.LEPTONS_PER_TILE&&(r=!0)}}else o.map.isWithinHardBounds(n)&&this.position.moveByLeptons3(t),r=!0;if(r){if(a&&s===CollisionType.Wall){let e=a.position.worldPosition;this.position.moveByLeptons3(e.clone().sub(this.position.worldPosition))}this.collisionType=s,this.detonate(o,s)}}else{let t=this.aimPoint.clone().sub(this.position.worldPosition);this.rules.vertical||(this.direction=FacingUtil.fromMapCoords(new Vector2(t.x,t.z))),this.rules.arcing&&(t.y=0);g=Math.min(t.length(),h);if(t.setLength(g),this.rules.arcing){let e=Coords.vecWorldToGround(this.position.worldPosition.clone().sub(this.initialSelfPosition).add(t));var m=this.aimPoint.clone().sub(this.initialSelfPosition),a=e.length(),u=Coords.vecWorldToGround(m).length(),y=m.y,m=o.rules.audioVisual.gravity;u&&(t.y=(y/u*h+m/2*u/h)*a/h-m*(a/h)*(a/h)/2+this.initialSelfPosition.y-this.position.worldPosition.y)}let e=!1;a=t.clone().add(this.position.worldPosition);o.map.isWithinHardBounds(a)?this.position.moveByLeptons3(t):e=!0;let i=CollisionType.None,r;if(1<=g?(g!==h&&!this.overshootTiles||this.velocity.copy(t),l=this.checkObstacles(l,o),i=l.type,r=l.target,(i||g<h)&&(e=!0)):e=!0,e){if(i){if(r&&i===CollisionType.Wall){let e=r.isBuilding()?Coords.tile3dToWorld(r.tile.rx+.5,r.tile.ry+.5,r.tile.z):r.position.worldPosition;this.position.moveByLeptons3(e.clone().sub(this.position.worldPosition))}}else if(this.overshootTiles){var T=Coords.vecWorldToGround(s).setLength(this.overshootTiles*Coords.LEPTONS_PER_TILE);if(rotateVec2(T,o.generateRandomInt(-45,45)),a=Coords.vecGroundToWorld(T).add(this.position.worldPosition),!o.map.isWithinHardBounds(a))return void o.unspawnObject(this);this.position.moveByLeptons(T.x,T.y)}else if(this.snapToTarget&&!this.targetLockLost){if(!o.map.isWithinHardBounds(n))return void o.unspawnObject(this);this.position.moveByLeptons3(n.clone().sub(this.position.worldPosition))}this.collisionType=i,this.isNuke?(this.state=ProjectileState.Impact,this.detonationTimer=2.5*GameSpeed.BASE_TICKS_PER_SECOND):this.detonate(o,i)}}let e=this.fromWeapon.warhead;if(e.rules.sonic){var t,i,T=11/30*Coords.LEPTONS_PER_TILE,T=this.position.worldPosition.clone().add(this.velocity.clone().setLength(T)),T=Coords.vecWorldToGround(T).multiplyScalar(1/Coords.LEPTONS_PER_TILE).floor(),r=o.map.tiles.getByMapCoords(T.x,T.y);if(r&&r!==this.fromObject?.tile){var f,v=o.map.getTileZone(r);for(f of o.map.getGroundObjectsOnTile(r))if((!f.isUnit()||!f.onBridge)&&(!f.isTechno()||!f.rules.typeImmune||f.owner!==this.fromPlayer||f.name!==this.fromObject?.name)&&(!f.isAircraft()||!f.rules.spawned)&&e.canDamage(f,r,v)){let e=this.sonicVisitedObjects.get(f)??new Set;e.add(r),this.sonicVisitedObjects.set(f,e)}}for([t,i]of this.sonicVisitedObjects)for(var b of i)o.map.tileOccupation.isTileOccupiedBy(b,t)&&t.isSpawned&&(b=this.fromWeapon.rules.ambientDamage*this.veteranDamageMult*this.baseDamageMultiplier,b=e.computeDamage(b,t,o),e.inflictDamage(b,t,{player:this.fromPlayer,weapon:this.fromWeapon,obj:this.fromObject},o,t!==this.target.obj))}}else 0<this.detonationTimer?this.detonationTimer--:this.detonate(o,this.collisionType)}isHoming(){return!!this.rot&&!this.rules.arcing}isInHomingRange(t,i){let r=!0,s=this.target.obj;if(s?.isUnit()&&this.fromObject){let e=new RangeHelper(this.tileOccupation);i=e.computeWeaponRangeVsTarget(this.fromObject,s,this.fromWeapon,i.rules).range;this.fromWeapon.rules.limboLaunch?r=e.isInRange3(this.initialSelfPosition,t,0,i+.5):(t=s.moveTrait.velocity.length())&&(this.fromObject.rules.movementZone===MovementZone.Fly?5<this.speed/t&&(r=e.isInRange2(this.initialSelfPosition,this.position.worldPosition,0,i)):isFinite(this.fromWeapon.speed)&&3.5<this.fromWeapon.speed/s.rules.speed&&(r=e.isInRange3(this.initialSelfPosition,this.position.worldPosition,0,i)))}return r}updateSpeed(e){let t;return t=this.isHoming()||this.rules.vertical?void 0===this.speed?Math.min(e,this.rules.acceleration):Math.min(e,this.speed+this.rules.acceleration):e,t}computeMaxSpeed(e,t,i){let r=e;return this.rules.arcing&&(r*=(1+i/6)/2,t=Math.floor(t),r*=t<=8?1:1+t/8*.5),this.fromWeapon.warhead.rules.sonic&&(r=Math.ceil(t*Coords.LEPTONS_PER_TILE/21)),r}checkObstacles(e,t){return this.fromWeapon.rules.limboLaunch?{type:CollisionType.None}:this.collisionHelper.checkCollisions(this.position,e,{cliffs:this.rules.subjectToCliffs,ground:this.isHoming(),shore:this.rules.level,walls:this.rules.subjectToWalls,units:!this.rules.inaccurate&&(e=>this.fromPlayer!==e&&!t.alliances.areAllied(this.fromPlayer,e))})}computeBaseDamage(e){var t=this.fromWeapon,i=t.warhead;let r=t.rules.damage;t.type===WeaponType.DeathWeapon&&i.rules.ivanBomb&&(r=e.rules.combatDamage.ivanDamage);let s=r*this.baseDamageMultiplier;return t.type===WeaponType.DeathWeapon&&this.fromObject&&(s*=this.fromObject.rules.deathWeaponDamageModifier),s*=this.veteranDamageMult,s}detonate(n,e=CollisionType.None){var i=this.fromWeapon;let r=i.warhead;var t,s=this.zone=this.collisionHelper.computeDetonationZone(this.tile,this.tileElevation,e);let o=this.tile;i.type===WeaponType.DeathWeapon&&r.rules.ivanBomb&&(r=new Warhead(n.rules.getWarhead(n.rules.combatDamage.ivanWarhead)));let a=this.computeBaseDamage(n);n.destroyObject(this),this.state=ProjectileState.Detonation;let l=this.target.obj,h=!1;if(r.rules.parasite&&l?.isUnit()&&o===l.tile&&r.canDamage(l,o,s))if(l.isInfantry())a=Number.POSITIVE_INFINITY;else if(l.parasiteableTrait&&this.fromObject?.isUnit()){if(!(this.fromWeapon instanceof Weapon))throw new Error("Projectile with parasite warhead must have a weapon reference");l.parasiteableTrait.infest(this.fromObject,this.fromWeapon),h=!0}let c=!0;if(h&&(c=!1),r.rules.sonic&&(c=!1),r.rules.ivanBomb&&(c=!1,!l?.isTechno()||!l.tntChargeTrait||l.tntChargeTrait.hasCharge()||l.isDestroyed||l.warpedOutTrait.isInvulnerable()||(t=n.rules.combatDamage.ivanTimedDelay,l.tntChargeTrait.setCharge(t,n.currentTick,{player:this.fromPlayer,obj:this.fromObject}))),r.rules.bombDisarm&&(c=!1,l?.isTechno()&&l.tntChargeTrait?.hasCharge()&&!l.isDestroyed&&l.tntChargeTrait.removeCharge()),r.rules.mindControl&&(c=!1,this.fromObject&&!this.fromObject.isDestroyed&&l?.isTechno()&&l.mindControllableTrait&&!l.mindControllableTrait?.isActive()&&!n.areFriendly(l,this.fromObject)&&r.canDamage(l,o,s)&&!l.invulnerableTrait.isActive()&&this.fromObject.mindControllerTrait.control(l,n)),r.rules.temporal&&(c=!1,this.fromObject&&!this.fromObject.isDestroyed&&l?.isTechno()&&r.canDamage(l,o,s)&&!l.invulnerableTrait.isActive()&&(r.inflictDamage(0,l,{player:this.fromPlayer,weapon:i,obj:this.fromObject},n),this.fromObject.temporalTrait.updateTarget(l,i,n))),r.rules.makesDisguise&&(c=!1,this.fromObject&&!this.fromObject.isDestroyed&&(this.fromObject.isInfantry()||this.fromObject.isVehicle())&&l?.isUnit()&&l.type===this.fromObject.type&&this.fromObject.disguiseTrait?.disguiseAs(l,this.fromObject,n)),r.rules.electricAssault&&(this.fromObject?.isUnit()&&!this.fromObject.isDestroyed&&l?.isBuilding()&&!l.isDestroyed&&l.overpoweredTrait&&l.owner===this.fromPlayer&&l.overpoweredTrait.chargeFrom(this.fromObject),c=!1),c&&r.detonate(n,a,o,this.tileElevation,this.position.worldPosition,s,e,this.target,{player:this.fromPlayer,weapon:i,obj:this.fromObject},this.isShrapnel?SpecialWarheadType.Shrapnel:SpecialWarheadType.None,this.impactAnim),r.rules.nukeMaker){let e;e=this.fromObject?(d=Weapon.factory(Weapon.NUKE_PAYLOAD_NAME,WeaponType.Primary,this.fromObject,n.rules),n.createProjectile(d.projectileRules.name,this.fromObject,d,this.target,!1)):n.createLooseProjectile(Weapon.NUKE_PAYLOAD_NAME,this.fromPlayer,this.target),e.isNuke=!0,e.impactAnim="NUKEBALL";var d=this.target.tile;e.position.moveToTileCoords(d.rx+.5,d.ry+.5),e.position.tileElevation=this.position.tileElevation,n.spawnObject(e,d)}if(this.rules.shrapnelCount&&this.rules.shrapnelWeapon&&((this.target.obj?!this.target.obj.isBuilding():n.map.getGroundObjectsOnTile(this.target.tile).some(e=>e.isTerrain()||e.isTechno())&&!i.projectileRules.isAntiAir)||this.isShrapnel)){let t=n.rules.getWeapon(this.rules.shrapnelWeapon);var u,p=n.rules.getProjectile(t.projectile);let i=this.rules.shrapnelCount,r=new RangeHelper(n.map.tileOccupation),e=new RadialTileFinder(n.map.tiles,n.map.mapBounds,o,{width:1,height:1},1,t.range,e=>r.isInTileRange(o,e,t.minimumRange,t.range)),s=new Set;for(;0<Math.floor(i);){var g,m=e.getNextTile();if(!m)break;for(g of n.map.tileOccupation.getObjectsOnTileByLayer(m,p.isAntiAir?LayerType.Air:LayerType.Ground).filter(e=>n.isValidTarget(e)&&(e.isTerrain()||e.isTechno()&&e.owner!==this.fromPlayer&&!n.alliances.areAllied(e.owner,this.fromPlayer)&&!(e.isInfantry()&&e.stance===StanceType.Paradrop))))if(!s.has(g)&&(s.add(g),i=Math.max(0,i-1-(g.isTechno()?.5:0)),Math.floor(i)<=0))break}for(u of s){var y=n.createTarget(u.isTerrain()?void 0:u,u.tile);this.createShrapnel(n,y,t.name)}i=Math.floor(i);let a=new RandomTileFinder(n.map.tiles,n.map.mapBounds,o,t.range,n,e=>r.isInTileRange(o,e,t.minimumRange,t.range));for(let e=0;e<i;e++){var T=a.getNextTile();if(!T)break;T=n.createTarget(void 0,T);this.createShrapnel(n,T,t.name)}}if(i.rules.limboLaunch&&!h&&this.fromObject?.isUnit()){let s=this.fromObject;r.rules.parasite&&(this.target.obj.isVehicle()||this.target.obj?.isAircraft())&&this.target.obj.parasiteableTrait&&(this.target.obj.parasiteableTrait.beingBoarded=!1);let t,a;i=s.rules.movementZone===MovementZone.Fly;if(i)t=o,a=!1;else{let i=this.target.obj.isUnit()&&this.target.obj.tile.onBridgeLandType&&!this.target.obj.onBridge?void 0:n.map.tileOccupation.getBridgeOnTile(o),r=new MovePositionHelper(n.map),e=new RadialTileFinder(n.map.tiles,n.map.mapBounds,o,{width:1,height:1},0,1,e=>{var t=n.map.tileOccupation.getBridgeOnTile(e);return 0<n.map.terrain.getPassableSpeed(e,s.rules.speedType,s.isInfantry(),!!t)&&r.isEligibleTile(e,t,i,o)&&(e===o||!n.map.terrain.findObstacles({tile:e,onBridge:i},s).length)});t=e.getNextTile(),a=!!t?.onBridgeLandType}t?(!i&&this.target.obj.isUnit()&&(s.onBridge=a,s.position.tileElevation=a?n.map.tileOccupation.getBridgeOnTile(t)?.tileElevation??0:0),n.unlimboObject(s,t),s.isInfantry()&&(s.position.subCell=this.target.obj.position.subCell),s.direction=this.direction):s.owner.removeOwnedObject(s)}}createShrapnel(e,t,i){let r=e.createLooseProjectile(i,this.fromPlayer,t);r.isShrapnel=!0,r.veteranDamageMult=this.veteranDamageMult,r.position.moveToLeptons(this.position.getMapPosition()),r.position.tileElevation=this.position.tileElevation,e.spawnObject(r,r.position.tile)}computeAimPointVersusMovingTarget(t,i,e,r){let s=t.position.worldPosition,a=s.clone();var n=i,i=t.moveTrait.velocity.length();if(n<3*i)return s.clone();let o=TargetUtil.computeInterceptPoint(e,n,s,t.moveTrait.velocity);if(o.length()){let e=o.clone().sub(s);n=e.length(),i=i,n=i?Math.ceil(n/i):0;if(o=s.clone().add(e.setLength(n*i)),r.isWithinHardBounds(o))if(t.zone!==ZoneType.Air){o.multiplyScalar(1/Coords.LEPTONS_PER_TILE);let e=t.position.clone();e.moveToTileCoords(o.x,o.z),a=e.worldPosition}else a=o;else a=s}return a.clone()}}const DEPLOY_FIRE_DELAY_TICKS=15;!function(e){e[e.None=0]="None",e[e.PreparingToFire=1]="PreparingToFire",e[e.FiringUp=2]="FiringUp",e[e.Firing=3]="Firing"}(DeployFireState=DeployFireState||{});class DeployerTrait{constructor(e){this.gameObject=e,this.deployed=!1,this.deployFireDelay=0,this.deployFireState=DeployFireState.None,this.fireUpDelay=0,this.deployFireCount=0}isDeployed(){return this.deployed}setDeployed(t){var e=this.deployed;if((this.deployed=t)!==e){let e=this.gameObject;e.isInfantry()&&(e.stance=t?StanceType.Deployed:StanceType.None),t?(this.deployFireState=DeployFireState.PreparingToFire,t=this.gameObject.armedTrait?.getDeployFireWeapon(),this.deployWeapon=t?.rules.areaFire?t:void 0,this.deployFireDelay=DEPLOY_FIRE_DELAY_TICKS+((t===e.primaryWeapon?e.secondaryWeapon:e.primaryWeapon)?.getCooldownTicks()??0),this.deployFireCount=0,this.undeployDelay=this.gameObject.rules.undeployDelay||void 0):(this.deployFireState===DeployFireState.FiringUp&&(e.isFiring=!1),this.deployFireState=DeployFireState.None,this.deployWeapon=void 0)}}toggleDeployed(){this.setDeployed(!this.isDeployed())}[NotifyTick_NotifyTick.onTick](e,t){if(void 0!==this.undeployDelay&&(0<this.undeployDelay&&this.undeployDelay--,this.undeployDelay<=0&&[DeployFireState.None,DeployFireState.PreparingToFire].includes(this.deployFireState)))return this.undeployDelay=void 0,void this.setDeployed(!1);if(this.deployWeapon&&this.deployFireState!==DeployFireState.None){if(this.deployFireState===DeployFireState.PreparingToFire){if(0<this.deployFireDelay--||0===e.ammo)return;if(0<this.computeDeployFireCooldown(this.deployWeapon,t))return;this.fireUpDelay=Math.max(1,e.art.fireUp),this.deployFireState=DeployFireState.FiringUp}if(this.deployFireState===DeployFireState.FiringUp){if(e.isFiring=!0,0<this.fireUpDelay--)return;this.deployFireState=DeployFireState.Firing}var i;this.deployFireState===DeployFireState.Firing&&(e.isFiring=!1,i=e.onBridge?t.map.tileOccupation.getBridgeOnTile(e.tile):void 0,this.deployWeapon.fire(t.createTarget(i,e.tile),t),this.deployFireCount++,(this.deployWeapon===e.primaryWeapon?e.secondaryWeapon:e.primaryWeapon)?.resetCooldown(),this.deployWeapon.rules.fireOnce?(this.deployFireState=DeployFireState.None,this.deployWeapon=void 0):this.deployFireState=DeployFireState.PreparingToFire)}}computeDeployFireCooldown(t,i){if(t.rules.radLevel&&t.rules.areaFire){var r=this.gameObject.tile,r=i.mapRadiationTrait.getRadSiteLevel(r);if(!r)return 0;i=i.rules.radiation;let e=Math.max(0,r*i.radDurationMultiple-i.radLevelDelay);return 1===this.deployFireCount&&(i=i.radDurationMultiple*t.rules.radLevel,e=Math.max(0,e-Math.floor(.25*i))),e}return t.getCooldownTicks()}getHash(){return this.deployed?1:0}debugGetState(){return{deployed:this.deployed}}dispose(){this.gameObject=void 0}}(NotifyHealthChange=NotifyHealthChange||{}).onChange=Symbol();class InflictDamageEvent{constructor(e,t,i,r,s){this.target=e,this.attacker=t,this.damageHitPoints=i,this.currentHealth=r,this.prevHealth=s,this.type=EventType.InflictDamage}}(NotifyHealthChange_NotifyHealthChange=NotifyHealthChange_NotifyHealthChange||{}).onChange=Symbol(),function(e){e[e.Green=0]="Green",e[e.Yellow=1]="Yellow",e[e.Red=2]="Red"}(HealthLevel=HealthLevel||{});class HealthChangeEvent{constructor(e,t,i){this.target=e,this.currentHealth=t,this.prevHealth=i,this.type=EventType.HealthChange}}const MIN_PROJECTED_HIT_POINTS=-30,PROJECTED_HEALTH_DECAY_FRAMES=4;class HealthTrait{get health(){return this._computedHealth}set health(e){this.setHitPoints(0<e?Math.max(1,Math.floor(e*this.maxHitPoints/100)):0),this.projectedHitPoints=this.hitPoints}get level(){return this.health>100*this.conditionYellow?HealthLevel.Green:this.health>100*this.conditionRed?HealthLevel.Yellow:HealthLevel.Red}constructor(e,t,i,r){this.maxHitPoints=e,this.gameObject=t,this.conditionYellow=i,this.conditionRed=r,this.setHitPoints(e),this.projectedHitPoints=this.hitPoints}setHitPoints(e){if(e!==Math.floor(e))throw new Error(`Value ${e} is not an integer`);this.hitPoints=clamp(e,0,this.maxHitPoints),this._computedHealth=this.hitPoints/this.maxHitPoints*100}getHitPoints(){return this.hitPoints}getProjectedHitPoints(){return this.projectedHitPoints}inflictDamage(t,i,r){var e=this.hitPoints,s=this.health;this.applyHitPoints(e-t,r),e!==this.hitPoints&&0<t&&(this.gameObject.traits.filter(NotifyDamage).forEach(e=>{e[NotifyDamage.onDamage](this.gameObject,r,t,i)}),r.events.dispatch(new InflictDamageEvent(this.gameObject,i,t,this.health,s)))}healBy(e,i,r){if(e<0)throw new Error("Can't heal by negative value "+e);if(this.hitPoints<this.maxHitPoints){var s=this.hitPoints;this.applyHitPoints(this.hitPoints+e,r),this.projectedHitPoints=this.hitPoints;let t=this.hitPoints-s;this.gameObject.traits.filter(NotifyHeal).forEach(e=>{e[NotifyHeal.onHeal]?.(this.gameObject,r,t,i)})}}healToFull(i,r){if(this.hitPoints<this.maxHitPoints){var e=this.hitPoints;this.applyHitPoints(this.maxHitPoints,r),this.projectedHitPoints=this.hitPoints;let t=this.hitPoints-e;this.gameObject.traits.filter(NotifyHeal).forEach(e=>{e[NotifyHeal.onHeal]?.(this.gameObject,r,t,i)})}}applyHitPoints(e,t){let i=this.health;this.setHitPoints(e),i!==this.health&&(t.traits.filter(NotifyHealthChange).forEach(e=>{e[NotifyHealthChange.onChange](this.gameObject,t,i)}),this.gameObject.traits.filter(NotifyHealthChange_NotifyHealthChange).forEach(e=>{e[NotifyHealthChange_NotifyHealthChange.onChange](this.gameObject,t,i)}),t.events.dispatch(new HealthChangeEvent(this.gameObject,this.health,i)))}projectDamage(e){if(e<0)throw new Error("Projected damage must be positive");this.projectedHitPoints=Math.max(MIN_PROJECTED_HIT_POINTS,this.projectedHitPoints-e)}[NotifyTick_NotifyTick.onTick](e,t){t.currentTick%PROJECTED_HEALTH_DECAY_FRAMES==0&&(this.projectedHitPoints=Math.min(this.projectedHitPoints+1,this.hitPoints))}getHash(){return this.hitPoints}debugGetState(){return{hitPoints:this.hitPoints}}dispose(){this.gameObject=void 0}}class BridgeTrait{constructor(e){this.bridges=e,this.needsImageUpdate=!1,this.dominoHandled=!1}[NotifyDamage.onDamage](){this.needsImageUpdate=!0}[NotifyTick_NotifyTick.onTick](e){this.needsImageUpdate&&(this.needsImageUpdate=!1,this.bridges.handlePieceHealthChange(this.bridges.getPieceAtTile(e.tile)))}[NotifyDestroy.onDestroy](s,a,n){var e=this.bridges.getPieceAtTile(s.tile);this.dominoHandled||this.bridges.findDominoPieces(e).filter(e=>!e.obj.isDestroyed).forEach(e=>{e.obj.traits.get(BridgeTrait).dominoHandled=!0,a.destroyObject(e.obj,n)});let t=a.map.tileOccupation.calculateTilesForGameObject(s.tile,s);t.forEach(e=>{let i=getLandType(e.terrainType),r=a.rules.getLandRules(i);a.map.getGroundObjectsOnTile(e).forEach(e=>{if(e.isUnit()&&(e.onBridge||e.moveTrait.reservedPathNodes.some(e=>e.onBridge===s))&&!e.isDestroyed)if(s.isLowBridge()&&0<r.getSpeedModifier(e.rules.speedType)||e.isInfantry()&&e.stance===StanceType.Paradrop){e.onBridge&&(e.onBridge=!1,e.zone=getZoneType(i));for(var t of e.moveTrait.reservedPathNodes)t.onBridge===s&&(t.onBridge=void 0);e.moveTrait.currentWaypoint?.onBridge===s&&(e.moveTrait.currentWaypoint.onBridge=void 0)}else e.isInfantry()&&(e.infDeathType=InfDeathType.None),a.destroyObject(e,n,!0)})})}}const SPAWN_RADIUS=2,SPAWN_BAILS=1,SPAWN_INITIAL_BAILS=3;!function(e){e[e.Idle=0]="Idle",e[e.Spawning=1]="Spawning"}(SpawnStatus=SpawnStatus||{});class TiberiumTreeTrait{constructor(e){this.rules=e,this.ticksSinceLastSpawn=0,this.cooldownTicks=Math.floor(1/this.rules.animationProbability),this.status=SpawnStatus.Idle}[NotifyTick_NotifyTick.onTick](e,t){this.status=SpawnStatus.Idle,this.ticksSinceLastSpawn++>this.cooldownTicks&&(this.ticksSinceLastSpawn=0,this.status=SpawnStatus.Spawning,this.spawnTiberium(e.tile,t))}spawnTiberium(r,s){for(let i=1;i<=SPAWN_RADIUS;i++){let e=new RadialTileFinder(s.map.tiles,s.map.mapBounds,r,{width:1,height:1},i,i,e=>TiberiumTrait.canBePlacedOn(e,s.map));var a=e.getNextTile();if(a){var n=OreSpread.calculateOverlayId(TiberiumType.Ore,a);if(void 0===n)throw new Error("Expected an overlayId");let e=s.createObject(ObjectType.Overlay,s.rules.getOverlayName(n));return e.overlayId=n,e.value=SPAWN_INITIAL_BAILS,void s.spawnObject(e,a)}e=new RadialTileFinder(s.map.tiles,s.map.mapBounds,r,{width:1,height:1},i,i,e=>e.landType===LandType.Tiberium);let t;for(;!t;){var o=e.getNextTile();if(!o)break;t=s.map.getObjectsOnTile(o).find(e=>e.isOverlay()&&e.isTiberium()&&e.traits.get(TiberiumTrait).getBailCount()+SPAWN_BAILS<=TiberiumTrait.maxBails)}if(t)return void t.traits.get(TiberiumTrait).spawnBails(SPAWN_BAILS)}}}class AutoRepairTrait{constructor(e=!1){this.freeRepair=e,this.disabled=!0,this.cooldownTicks=0,this.healLeftover=0}isDisabled(){return this.disabled}setDisabled(e){this.disabled=e}[NotifyTick_NotifyTick.onTick](t,i){if(!this.isDisabled())if(100===t.healthTrait.health&&this.setDisabled(!0),this.cooldownTicks<=0){var r=i.rules.general.repair,s=t.isInfantry()?r.iRepairRate:t.isBuilding()?r.repairRate:r.uRepairRate;this.cooldownTicks+=GameSpeed.BASE_TICKS_PER_SECOND*s*60;var a=t.isInfantry()?r.iRepairStep:r.repairStep,s=this.freeRepair?0:r.repairPercent;let e;s?(r=s*t.purchaseValue/t.healthTrait.maxHitPoints,(s=Math.min(t.owner.credits,Math.max(1,Math.floor(r*a))))?(e=r?s/r:a,t.owner.credits-=s):(e=0,this.setDisabled(!0))):e=a,e&&(e+=this.healLeftover,e=Math.min(t.healthTrait.maxHitPoints-t.healthTrait.getHitPoints(),e),e&&(a=Math.floor(e),this.healLeftover=e-a,a&&t.healthTrait.healBy(a,t,i)))}else this.cooldownTicks--}[NotifyOwnerChange.onChange](){this.setDisabled(!0)}}(NotifyTargetDestroy=NotifyTargetDestroy||{}).onDestroy=Symbol();class UnitPromoteEvent{constructor(e){this.target=e,this.type=EventType.UnitPromote}}class SelfHealingTrait{constructor(){this.cooldownTicks=0}[NotifyTick_NotifyTick.onTick](e,t){100!==e.healthTrait.health&&(this.cooldownTicks<=0?(this.cooldownTicks+=GameSpeed.BASE_TICKS_PER_SECOND*t.rules.general.repair.repairRate*60,e.healthTrait.healBy(1,e,t)):this.cooldownTicks--)}}class ArmedTrait{constructor(e,t){this.gameObject=e,this.rules=t,this.specialWeaponIndex=0;t=e.veteranLevel===VeteranLevel.Elite;e.rules.weaponCount?(this.selectSpecialWeapon(0,t),this.guardWeaponRangeOverride=this.primaryWeapon?.range):this.selectStandardWeapons(t)}selectStandardWeapons(e=!1){var t=this.gameObject,i=e&&t.rules.elitePrimary||t.rules.primary;i?(s=e?t.art.elitePrimaryFireFlh:t.art.primaryFireFlh,this.primaryWeapon=Weapon.factory(i,WeaponType.Primary,t,this.rules,s)):this.primaryWeapon=void 0;var r,s=e&&t.rules.eliteSecondary||t.rules.secondary;s?(r=e?t.art.eliteSecondaryFireFlh:t.art.secondaryFireFlh,this.secondaryWeapon=Weapon.factory(s,WeaponType.Secondary,t,this.rules,r)):this.secondaryWeapon=void 0,(t.explodes||t.crashableTrait)&&(r=t.rules.deathWeapon||!!t.crashableTrait&&this.secondaryWeapon?.rules.name||this.primaryWeapon?.rules.name||this.rules.combatDamage.deathWeapon,this.deathWeapon=Weapon.factory(r,WeaponType.DeathWeapon,t,this.rules))}selectSpecialWeapon(e,t=!1){let i=this.gameObject;var r=i.rules.weaponCount;if(r<1)throw new Error(`Object "${i.name}" doesn't support special weapons`);if(r-1<e)throw new RangeError(`Weapon index ${e} out of bounds (max ${r}) for object `+i.name);r=t&&i.rules.getEliteWeaponAtIndex(e)||i.rules.getWeaponAtIndex(e);if(!r)throw new Error(`Missing weapon at index ${e} for object "${i.name}"`);t=i.art.getSpecialWeaponFlh(e);this.primaryWeapon=Weapon.factory(r,WeaponType.Primary,i,this.rules,t),this.secondaryWeapon=void 0,this.specialWeaponIndex=e,this.deathWeapon=this.primaryWeapon.rules.suicide?Weapon.factory(i.rules.deathWeapon||this.primaryWeapon.name,WeaponType.DeathWeapon,i,this.rules):void 0}toggleEliteWeapons(e){this.gameObject.rules.weaponCount?this.selectSpecialWeapon(this.specialWeaponIndex,e):this.selectStandardWeapons(e)}getSpecialWeaponIndex(){return this.specialWeaponIndex}computeGuardScanRange(t){var e=this.guardWeaponRangeOverride??[this.primaryWeapon,this.secondaryWeapon].filter(e=>e===t||e?.rules.neverUse).reduce((e,t)=>Math.max(e,t.range),0),e=Math.max(e,this.gameObject.rules.guardRange);return Math.min(15,2*e-1)}getDeployFireWeapon(){if(this.gameObject.rules.deployFire)return this.gameObject.rules.deployFireWeapon===WeaponType.Primary?this.primaryWeapon:this.secondaryWeapon}isEquippedWithWeapon(e){return[this.primaryWeapon,this.secondaryWeapon].includes(e)}getWeapons(){return[this.primaryWeapon,this.secondaryWeapon].filter(isNotNullOrUndefined)}[NotifyTick_NotifyTick.onTick](){this.primaryWeapon&&this.primaryWeapon.tick(),this.secondaryWeapon&&this.secondaryWeapon.tick()}[NotifyDestroy.onDestroy](t,e,i){!this.deathWeapon||i?.weapon?.warhead.rules.temporal||t.crashableTrait&&!t.isCrashing||i?.obj?.isVehicle()&&i.weapon?.rules.suicide&&i.obj.transportTrait?.units.find(e=>e===t)||this.deathWeapon.fire(e.createTarget(t,t.tile),e)}dispose(){this.gameObject=void 0,this.primaryWeapon=void 0,this.secondaryWeapon=void 0,this.deathWeapon=void 0}}class SensorsTrait{}class VeteranTrait{constructor(e,t){this.gameObject=e,this.veteranRules=t,this.veteranLevel=VeteranLevel.None,this.xp=0,this.promotionThresh=e.rules.cost*t.veteranRatio+1}[NotifyTargetDestroy.onDestroy](e,t,i,r){e.isDestroyed&&!e.isCrashing||t.isTechno()&&(t.rules.dontScore||t.rules.insignificant||(i&&(i.warhead.rules.temporal||i.warhead.rules.parasite&&e.rules.organic)||!r.areFriendly(e,t))&&(this.veteranLevel>=this.veteranRules.veteranCap||this.gainXP(t.rules.cost*(t.veteranLevel+1))&&this.handlePromotion(e,r)))}setRelativeXP(e){this.gainXP(Math.floor(e*this.promotionThresh))}gainXP(e){if(this.xp+=e,this.xp>=this.promotionThresh){var t=Math.min(this.veteranLevel+Math.floor(this.xp/this.promotionThresh),this.veteranRules.veteranCap),e=t-this.veteranLevel;if(e)return this.xp-=e*this.promotionThresh,this.setVeteranLevel(t),!0}return!1}promote(e,t){e=Math.min(this.veteranLevel+e,this.veteranRules.veteranCap);e-this.veteranLevel&&(this.setVeteranLevel(e),this.handlePromotion(this.gameObject,t))}isMaxLevel(){return this.veteranLevel===this.veteranRules.veteranCap}isElite(){return this.veteranLevel===VeteranLevel.Elite}setVeteranLevel(e){this.veteranLevel=e,this.veteranLevel===VeteranLevel.Elite&&this.gameObject.armedTrait?.toggleEliteWeapons(!0)}handlePromotion(e,t){this.hasVeteranAbility(VeteranAbility.SELF_HEAL)&&(e.traits.find(SelfHealingTrait)||t.addObjectTrait(e,new SelfHealingTrait)),this.hasVeteranAbility(VeteranAbility.CLOAK)&&(e.cloakableTrait||(e.cloakableTrait=new CloakableTrait(e,t.rules.general.cloakDelay),t.addObjectTrait(e,e.cloakableTrait))),this.hasVeteranAbility(VeteranAbility.EXPLODES)&&(e.explodes||(e.explodes=!0,e.armedTrait||(e.armedTrait=new ArmedTrait(e,t.rules),t.addObjectTrait(e,e.armedTrait)))),this.hasVeteranAbility(VeteranAbility.RADAR_INVISIBLE)&&(e.radarInvisible||(e.radarInvisible=!0)),this.hasVeteranAbility(VeteranAbility.SENSORS)&&(e.sensorsTrait||(e.sensorsTrait=new SensorsTrait,t.addObjectTrait(e,e.sensorsTrait))),e.isInfantry()&&this.hasVeteranAbility(VeteranAbility.FEARLESS)&&e.suppressionTrait?.disable(),this.hasVeteranAbility(VeteranAbility.C4)&&(e.c4||(e.c4=!0)),this.hasVeteranAbility(VeteranAbility.GUARD_AREA)&&(e.defaultToGuardArea||(e.defaultToGuardArea=!0,e.unitOrderTrait.isIdle()&&e.resetGuardModeToIdle())),this.hasVeteranAbility(VeteranAbility.CRUSHER)&&(e.crusher||(e.crusher=!0)),t.events.dispatch(new UnitPromoteEvent(e))}getVeteranSightMultiplier(){return this.getVeteranAbilityMultiplier(VeteranAbility.SIGHT)}getVeteranSpeedMultiplier(){return this.getVeteranAbilityMultiplier(VeteranAbility.FASTER)}getVeteranArmorMultiplier(){return this.getVeteranAbilityMultiplier(VeteranAbility.STRONGER)}getVeteranDamageMultiplier(){return this.getVeteranAbilityMultiplier(VeteranAbility.FIREPOWER)}getVeteranRofMultiplier(){return this.getVeteranAbilityMultiplier(VeteranAbility.ROF)}hasVeteranAbility(e){return this.veteranLevel===VeteranLevel.Veteran&&this.gameObject.rules.veteranAbilities.has(e)||this.veteranLevel>=VeteranLevel.Elite&&this.gameObject.rules.eliteAbilities.has(e)}getVeteranAbilityMultiplier(e){let t=1;return(this.veteranLevel===VeteranLevel.Veteran&&this.gameObject.rules.veteranAbilities.has(e)||this.veteranLevel>=VeteranLevel.Elite&&this.gameObject.rules.eliteAbilities.has(e))&&(t=this.getVeteranRulesMultiplier(e)),t}getVeteranRulesMultiplier(e){switch(e){case VeteranAbility.FASTER:return this.veteranRules.veteranSpeed;case VeteranAbility.STRONGER:return this.veteranRules.veteranArmor;case VeteranAbility.FIREPOWER:return this.veteranRules.veteranCombat;case VeteranAbility.ROF:return this.veteranRules.veteranROF;case VeteranAbility.SIGHT:return this.veteranRules.veteranSight;default:throw new Error("Unhandled VeteranAbility "+e)}}dispose(){this.gameObject=void 0}}class AmmoTrait{constructor(e,t=e){this.maxAmmo=e,this.ammo=t}get ammo(){return this._ammo}set ammo(e){this._ammo=clamp(e,0,this.maxAmmo)}isFull(){return this.ammo===this.maxAmmo}}class ObjectDisguiseChangeEvent{constructor(e){this.target=e,this.type=EventType.ObjectDisguiseChange}}class DisguiseTrait{constructor(){this.isActive=!1,this.cooldownTicks=0}isDisguised(){return this.isActive}getDisguise(){return this.isActive?this.disguisedAs:void 0}hasTerrainDisguise(){return this.getDisguise()?.rules.type===ObjectType.Terrain}disguiseAs(e,t,i){this.disguisedAs={rules:e.rules,owner:e.owner},this.isActive=!0,i.events.dispatch(new ObjectDisguiseChangeEvent(t))}revealDisguise(e,t){this.cooldownTicks=t.rules.general.infantryBlinkDisguiseTime,this.isActive=!1,t.events.dispatch(new ObjectDisguiseChangeEvent(e))}[NotifySpawn.onSpawn](e,t){var i;!this.disguisedAs&&e.rules.permaDisguise&&e.isInfantry()&&e.owner.country&&((i=this.getDefaultInfantryDisguise(e.owner.country.side,t.rules.general))&&(i=t.rules.getObject(i,ObjectType.Infantry),this.disguisedAs={rules:i,owner:e.owner},this.isActive=!0))}getDefaultInfantryDisguise(e,t){switch(e){case SideType.GDI:return t.alliedDisguise;case SideType.Nod:return t.sovietDisguise;case SideType.ThirdSide:return t.thirdDisguise;default:return}}[NotifyTick_NotifyTick.onTick](e,t){e.rules.permaDisguise||(e.attackTrait?.attackState===AttackState.JustFired||e.moveTrait.moveState!==MoveState.Idle?this.revealDisguise(e,t):0<this.cooldownTicks?this.cooldownTicks--:!this.isActive&&e.rules.disguiseWhenStill&&(this.isActive=!0,this.disguisedAs={rules:this.selectRandomMirageDisguise(t),owner:void 0},t.events.dispatch(new ObjectDisguiseChangeEvent(e))))}[NotifyDamage.onDamage](e,t){this.revealDisguise(e,t)}selectRandomMirageDisguise(e){var t=e.rules.general.defaultMirageDisguises;if(!t.length)throw new Error("No default mirage disguises are defined");t=t[e.generateRandomInt(0,t.length-1)];return e.rules.getObject(t,ObjectType.Terrain)}}class InvulnerableTrait{constructor(){this.timer=new Timer}isActive(){return this.timer.isActive()}setActiveFor(e,t){this.timer.setActiveFor(e,t)}[NotifyTick_NotifyTick.onTick](e,t){this.timer.tick(t.currentTick)}}class WarpedOutTrait{constructor(e){this.gameObject=e,this.ticksWhenWarpedOut=!0,this.remainingTicks=0,this.invulnerable=!1}isActive(){return 0<this.remainingTicks}setActive(e,t,i){this.remainingTicks=e?Number.POSITIVE_INFINITY:0,this.invulnerable=t,this.notifyChange(e,i)}setTimed(e,t,i){this.remainingTicks=e,this.invulnerable=t,this.notifyChange(!0,i)}debugSetActive(e){this.remainingTicks=e?Number.POSITIVE_INFINITY:0}notifyChange(t,i){i.traits.filter(NotifyWarpChange).forEach(e=>{e[NotifyWarpChange.onChange](this.gameObject,i,t)}),this.gameObject.traits.filter(NotifyWarpChange_NotifyWarpChange).forEach(e=>{e[NotifyWarpChange_NotifyWarpChange.onChange](this.gameObject,i,t)})}expire(e){this.remainingTicks=0,this.notifyChange(!1,e)}isInvulnerable(){return this.isActive()&&this.invulnerable}[NotifyTick_NotifyTick.onTick](e,t){0<this.remainingTicks&&(this.remainingTicks--,this.remainingTicks<=0&&this.notifyChange(!1,t))}dispose(){this.gameObject=void 0}}class TntChargeTrait{constructor(){this.timer=new Timer}hasCharge(){return this.timer.isActive()}setCharge(e,t,i){this.hasCharge()||(this.timer.setActiveFor(e,t),this.attackerInfo=i)}getChargeOwner(){return this.attackerInfo?.player}removeCharge(){this.timer.reset()}getTicksLeft(){return this.timer.getTicksLeft()}getInitialTicks(){return this.timer.getInitialTicks()}[NotifyTick_NotifyTick.onTick](e,t){this.timer.isActive()&&!0===this.timer.tick(t.currentTick)&&(e.isBuilding()&&e.cabHutTrait&&e.cabHutTrait.demolishBridge(t,this.attackerInfo),this.detonateIvanWarhead(t,e))}[NotifyDestroy.onDestroy](e,t,i){!this.timer.isActive()||i?.weapon?.warhead.rules.ivanBomb||[DeathType.None,DeathType.Temporal,DeathType.Sink].includes(e.deathType)||(this.timer.reset(),this.detonateIvanWarhead(t,e))}detonateIvanWarhead(e,t){var i=e.rules.combatDamage.ivanDamage;let r=new Warhead(e.rules.getWarhead(e.rules.combatDamage.ivanWarhead));var s=t.tile,a=t.tileElevation,n=t.isUnit()?t.zone:e.map.getTileZone(s),o=!!t.isUnit()&&t.onBridge;r.detonate(e,i,s,a,t.isBuilding()?Coords.tile3dToWorld(s.rx+.5,s.ry+.5,s.z+a):t.position.worldPosition,n,o?CollisionType.OnBridge:CollisionType.None,e.createTarget(t,s),{...this.attackerInfo,weapon:void 0},SpecialWarheadType.TntCharge)}}class MindControllableTrait{constructor(e){this.gameObject=e}getOriginalOwner(){return this.prevOwner}isActive(){return!!this.controller}getController(){return this.controller}controlBy(e,t){if(this.controller)throw new Error(`Object "${this.gameObject?.name}" is already mind controlled by "${e.name}"`);this.controller=e,this.prevOwner=this.gameObject.owner,t.changeObjectOwner(this.gameObject,e.owner)}restore(t){if(this.prevOwner){let e=this.prevOwner;this.prevOwner.defeated&&(e=t.getCivilianPlayer()),t.changeObjectOwner(this.gameObject,e),this.prevOwner=void 0,this.controller=void 0}}[NotifyUnspawn.onUnspawn](e,t){this.controller&&(this.controller.mindControllerTrait.cleanTarget(e),!e.isDestroyed&&e.limboData&&this.restore(t))}dispose(){this.gameObject=void 0}}class MindControllerTrait{constructor(e,t=1){this.gameObject=e,this.maxCapacity=t,this.targets=[]}isActive(){return 0<this.targets.length}isAtCapacity(){return this.targets.length===this.maxCapacity}getTargets(){return this.targets}control(e,t){if(!this.gameObject)throw new Error("Trait already disposed");if(!e.mindControllableTrait)throw new Error(`Target "${e.name}" cannot be mind controlled`);if(e.isDisposed)throw new Error(`Target "${e.name}" is disposed`);for(e.mindControllableTrait.controlBy(this.gameObject,t),this.targets.push(e);this.targets.length>this.maxCapacity;){let e=this.targets.shift();e.mindControllableTrait.restore(t)}}cleanTarget(e){e=this.targets.indexOf(e);-1!==e&&this.targets.splice(e,1)}[NotifyUnspawn.onUnspawn](e,t){for(var i of this.targets)i.mindControllableTrait.restore(t);this.targets.length=0}dispose(){this.gameObject=void 0}}class TemporalTrait{constructor(e){this.gameObject=e,this.ticksWhenWarpedOut=!0,this.attackers=new Set}[NotifyTick_NotifyTick.onTick](e,t){if(e.attackTrait&&(e.attackTrait.currentTarget&&!e.warpedOutTrait.isActive()||this.releaseCurrentTarget(t)),void 0!==this.eraseTicks)for(var i of this.attackers){var r=i.temporalTrait.currentWeapon;if(!r)throw new Error(`Attacker "${i.name}" is no longer targeting "${e.name}"`);var s=r.rules.damage;if(this.eraseTicks-=s,this.eraseTicks<=0){e.deathType=DeathType.Temporal,t.destroyObject(e,{player:i.owner,obj:i,weapon:r},!0),this.eraseTicks=void 0;break}}}getTarget(){return this.currentTarget}updateTarget(t,e,i){if(this.currentTarget!==t){this.releaseCurrentTarget(i),this.currentTarget=t,this.currentWeapon=e;e=t.temporalTrait.attackers.size;if(t.temporalTrait.attackers.add(this.gameObject),!e){t.warpedOutTrait.setActive(!0,!0,i);let e=t.unitOrderTrait.getCurrentTask();(e&&e instanceof AttackTask||e instanceof MoveTask)&&e.cancel(),t.temporalTrait.eraseTicks=10*t.healthTrait.maxHitPoints}}}releaseCurrentTarget(t){if(this.currentTarget){if(!this.currentTarget.isDisposed){let e=this.currentTarget.temporalTrait.attackers;e.delete(this.gameObject),e.size||(this.currentTarget.warpedOutTrait.expire(t),this.currentTarget.temporalTrait.eraseTicks=void 0)}this.currentTarget=void 0,this.currentWeapon=void 0}}[NotifyDestroy.onDestroy](e,t){this.releaseCurrentTarget(t)}dispose(){this.gameObject=void 0,this.attackers.clear()}}class AirSpawnTrait{constructor(){this.spawns=[],this.storage=[],this.missileLaunches=[],this.nextRegenTicks=[]}get availableSpawns(){return this.storage.length}debugSetStorage(e,t){this.storage.length=t,this.storage.fill(e,0,t)}isLaunchingMissiles(){return 0<this.missileLaunches.length}[NotifySpawn.onSpawn](t,i){var r=i.rules.getObject(t.rules.spawns,ObjectType.Aircraft);for(let e=0;e<t.rules.spawnsNumber;e++)this.pushNewSpawn(r,i,t)}[NotifyUnspawn.onUnspawn](e,t){this.destroySpawns(e,t)}[NotifyDestroy.onDestroy](e,t,i,r){this.destroySpawns(e,t,i,r)}pushNewSpawn(e,t,i){let r=t.createUnitForPlayer(e,i.owner);r.limboData={selected:!1,controlGroup:void 0},e.missileSpawn&&(r.pitch=90*t.rules.general.getMissileRules(e.name).pitchInitial),this.spawns.push(r),this.storage.push(r)}destroySpawns(e,t,i,r){for(var s of this.spawns)s.isDestroyed||(s.isSpawned&&!s.rules.missileSpawn&&s.crashableTrait?s.crashableTrait.crash(i):(s.isSpawned||(s.armedTrait&&(s.armedTrait.deathWeapon=void 0),s.position.tileElevation=e.position.tileElevation,s.zone=e.isUnit()?e.zone:ZoneType.Ground,s.onBridge=!!e.isUnit()&&e.onBridge,s.position.tile=e.tile),t.destroyObject(s,i,r)));this.spawns.length=0,this.storage.length=0,this.missileLaunches.length=0}[NotifyTick_NotifyTick.onTick](s,a){var t;if(this.spawns=this.spawns.filter(e=>!e.isDestroyed),this.missileLaunches=this.missileLaunches.filter(e=>!e.missile.isDestroyed),this.spawns.length<s.rules.spawnsNumber){var i=s.rules.spawnsNumber-this.spawns.length,r=a.rules.getObject(s.rules.spawns,ObjectType.Aircraft);for(let e=0;e<i;e++)r.missileSpawn&&e&&void 0===this.nextRegenTicks[e]?this.nextRegenTicks[e]=this.nextRegenTicks[0]:((t=this.nextRegenTicks)[e]??(t[e]=s.rules.spawnRegenRate),0<this.nextRegenTicks[e]&&this.nextRegenTicks[e]--),this.nextRegenTicks[e]<=0&&this.pushNewSpawn(r,a,s);this.nextRegenTicks=this.nextRegenTicks.filter(e=>0<e)}if(this.storage.length){if(this.nextReloadTicks??(this.nextReloadTicks=s.rules.spawnReloadRate),0<this.nextReloadTicks&&this.nextReloadTicks--,this.nextReloadTicks<=0){for(var e of this.storage)e.ammoTrait&&e.ammoTrait.ammo<e.ammoTrait.maxAmmo&&e.ammoTrait.ammo++;this.nextReloadTicks=s.rules.spawnReloadRate}}else this.nextReloadTicks=void 0;for(let r of this.missileLaunches.slice()){var n=a.rules.general.getMissileRules(r.missile.name);if(r.pauseFrames??(r.pauseFrames=n.pauseFrames),0<r.pauseFrames&&r.pauseFrames--,r.pauseFrames<=0){var o=90*n.pitchFinal,n=90*(n.pitchFinal-n.pitchInitial)/n.tiltFrames;let i=r.missile;if(i.pitch<o)i.pitch=Math.min(o,i.pitch+n);else{i.unitOrderTrait.addTask(new TaskGroup(new MoveTask(a,r.targetTile,!!r.targetBridge),new CallbackTask(()=>{var e,t;i.isDestroyed||(a.unspawnObject(i),i.dispose(),t=Coords.vecGroundToWorld(FacingUtil.toMapCoords(i.direction).multiplyScalar(1)),e=r.targetWorldPos.clone().add(t),t=a.map.getTileZone(r.targetTile),r.warhead.detonate(a,r.damage,r.targetTile,r.targetBridge?.tileElevation??0,e,t,r.targetBridge?CollisionType.OnBridge:CollisionType.None,r.target,{player:i.owner,obj:s,weapon:void 0}))})).setCancellable(!1));n=this.spawns.indexOf(i);if(-1===n)throw new Error("Missile not found in spawns list");this.spawns.splice(n,1),this.missileLaunches.splice(this.missileLaunches.indexOf(r),1)}}}}[NotifyOwnerChange.onChange](e,t,i){for(var r of this.spawns)r.isDestroyed||i.changeObjectOwner(r,e.owner)}[NotifyWarpChange_NotifyWarpChange.onChange](e,t,i){i&&this.removeMissileLaunches(t)}[NotifyTeleport.onBeforeTeleport](e,t,i,r){r||this.removeMissileLaunches(t)}removeMissileLaunches(e){if(this.missileLaunches.length){for(var t of this.missileLaunches){e.unspawnObject(t.missile),t.missile.dispose();t=this.spawns.indexOf(t.missile);if(-1===t)throw new Error("Missile not found in spawns list");this.spawns.splice(t,1)}this.missileLaunches.length=0}}prepareLaunch(r,s,a){if(this.storage.length){let i=this.storage[0];if(!i.ammo)return;if(this.storage.shift(),i.missileSpawnTrait){let e,t;var n=r.veteranTrait?.isElite(),o=a.rules;if(r.rules.spawns===o.general.v3Rocket.type)e=n?o.combatDamage.v3EliteWarhead:o.combatDamage.v3Warhead,t=n?o.general.v3Rocket.eliteDamage:o.general.v3Rocket.damage;else{if(r.rules.spawns!==o.general.dMisl.type)throw new Error(`Unhandled missile type "${r.rules.spawns}"`);e=n?o.combatDamage.dMislEliteWarhead:o.combatDamage.dMislWarhead,t=n?o.general.dMisl.eliteDamage:o.general.dMisl.damage}a=new Warhead(a.rules.getWarhead(e));i.missileSpawnTrait.setDamage(t).setWarhead(a).setLauncher(r),this.missileLaunches.push({missile:i,targetTile:(s.obj?.isUnit()?s.obj:s).tile,targetBridge:s.getBridge(),targetWorldPos:s.getWorldCoords().clone(),target:s,warhead:a,damage:t,pauseFrames:void 0})}else{if(!i.spawnLinkTrait)throw new Error(`Aircraft "${i.name}" must have Spawned=yes to be launchable`);i.spawnLinkTrait.setParent(r)}return i}}storeAircraft(e,t){if(!this.spawns.includes(e))throw new Error(`Object "${e.name}#${e.id}" not found in list of linked spawns`);if(e.limboData)throw new Error(`Object "${e.name}#${e.id}" is already in limbo`);t.limboObject(e,{selected:!1,controlGroup:void 0}),this.storage.push(e)}}class SpawnDebrisTrait{[NotifyCrash.onCrash](e,t){this.handleDestroy(e,t)}[NotifyDestroy.onDestroy](e,t,i){i?.weapon?.warhead.rules.temporal||e.isCrashing||e.deathType!==DeathType.Sink&&e.isSpawned&&this.handleDestroy(e,t)}handleDestroy(e,t){var i,r;(e.isVehicle()||e.isBuilding()||e.isOverlay())&&(i=e.isOverlay()?0:e.rules.minDebris,r=e.isOverlay()?t.rules.general.bridgeVoxelMax:e.rules.maxDebris,0<(r=t.generateRandomInt(i,r))&&this.spawnDebris(e,t,r))}spawnDebris(t,i,r){let s=t.position.getMapPosition();if(i.map.isWithinHardBounds(s)){let e=t.isOverlay()?[]:t.isVehicle()?t.rules.debrisTypes:t.rules.debrisAnims;e.length||(e=i.rules.audioVisual.metallicDebris),e=e.filter(e=>i.rules.hasObject(e,ObjectType.VoxelAnim)||i.art.hasObject(e,ObjectType.Animation)),new Array(r).fill(0).map(()=>e[i.generateRandomInt(0,e.length-1)]).map(e=>i.createObject(ObjectType.Debris,e)).forEach(e=>{e.position.moveToLeptons(s),e.position.tileElevation=t.position.tileElevation,i.spawnObject(e,e.position.tile)})}}}class Debris extends GameObject{static factory(e,t,i,r){return new this(e,t,i,r)}constructor(e,t,i,r){super(ObjectType.Debris,e,t,i),this.age=0,this.direction=0,this.rotationAxis=new Vector3_Vector3,this.angularVelocity=0,this.zone=ZoneType.Air,this.velocity=new Vector3_Vector3,this.collisionHelper=new CollisionHelper(r)}onSpawn(e){super.onSpawn(e),this.direction=e.generateRandomInt(0,359),this.xySpeed=lerp(0,this.rules.maxXYVel,e.generateRandom()),this.zSpeed=lerp(this.rules.minZVel,this.rules.maxZVel||1.5*this.rules.minZVel,e.generateRandom()),this.rotationAxis.set(e.generateRandom(),e.generateRandom(),e.generateRandom()).normalize(),this.angularVelocity=lerp(this.rules.minAngularVelocity,this.rules.maxAngularVelocity,e.generateRandom())}update(t){if(super.update(t),this.age++,this.rules.duration&&this.age>this.rules.duration)return this.velocity.set(0,0,0),void this.detonate(t);--this.zSpeed;var i=FacingUtil.toMapCoords(this.direction).setLength(this.xySpeed);let r=new Vector3_Vector3(i.x,this.zSpeed,i.y);var s=this.position.clone(),i=r.clone().add(this.position.worldPosition);if(t.map.isWithinHardBounds(i)){this.position.moveByLeptons3(r);let e=!1;var{type:i,target:s}=this.collisionHelper.checkCollisions(this.position,s,{cliffs:!0,ground:!0,shore:!1,walls:!0,units:!1});if(i&&(!([CollisionType.Ground,CollisionType.OnBridge].includes(i)&&0<this.rules.elasticity&&t.map.getTileZone(this.tile)!==ZoneType.Water)||Math.abs(this.zSpeed)<1?e=!0:(this.zSpeed=-this.zSpeed*this.rules.elasticity,this.velocity.y=-this.velocity.y*this.rules.elasticity,this.rotationAxis.negate())),e){if(this.velocity.set(0,0,0),s&&i===CollisionType.Wall){let e=s.position.worldPosition;this.position.moveByLeptons3(e.clone().sub(this.position.worldPosition))}this.detonate(t,i)}else this.velocity.copy(r)}else t.unspawnObject(this)}detonate(t,i=CollisionType.None){var e,r=this.rules.warhead?t.rules.getWarhead(this.rules.warhead):void 0,s=this.zone=this.collisionHelper.computeDetonationZone(this.tile,this.tileElevation,i);let a;s===ZoneType.Water?(e=t.rules.combatDamage.splashList,a=e[0]):(e=this.rules.expireAnim)&&t.rules.animationNames.has(e)&&(a=e),this.explodeAnim=a;let n=new AnimTerrainEffect;if(a&&n.spawnSmudges(a,this.tile,t),t.destroyObject(this),r){let e=new Warhead(r);e.detonate(t,this.rules.damage,this.tile,this.tileElevation,this.position.worldPosition,s,i,t.createTarget(void 0,this.tile),void 0,SpecialWarheadType.None,void 0,this.rules.damageRadius||void 0,!0)}}}class ObjectFactory{constructor(e,t,i,r){this.tiles=e,this.tileOccupation=t,this.bridges=i,this.nextObjectId=r}create(e,t,i,r){let s,a;e===ObjectType.Debris?s=i.hasObject(t,ObjectType.VoxelAnim)?(a=r.getObject(t,ObjectType.VoxelAnim),i.getObject(t,ObjectType.VoxelAnim)):(a=r.getAnimation(t),new DebrisRules(ObjectType.Debris,r.getIni().getOrCreateSection(t))):a=e===ObjectType.Projectile?(s=i.getProjectile(t),s.inviso?new ObjectArt(ObjectType.Projectile,s,new IniSection(t)):r.getProjectile(t)):(s=i.getObject(t,e),r.getObject(t,e));let n;switch(e){case ObjectType.Building:n=Building.factory(t,s,i,a,this.tiles,this.bridges);break;case ObjectType.Infantry:n=Infantry_Infantry.factory(t,s,a,this.tileOccupation);break;case ObjectType.Vehicle:n=Vehicle_Vehicle.factory(t,s,a,i,this.tileOccupation);break;case ObjectType.Aircraft:n=Aircraft_Aircraft.factory(t,s,a,i,this.tileOccupation);break;case ObjectType.Terrain:n=Terrain_Terrain.factory(t,s,a);break;case ObjectType.Overlay:n=Overlay_Overlay.factory(t,s,a);break;case ObjectType.Smudge:n=Smudge_Smudge.factory(t,s,a);break;case ObjectType.Projectile:n=Projectile.factory(t,s,a,this.tileOccupation);break;case ObjectType.Debris:n=Debris.factory(t,s,a,this.tileOccupation);break;default:throw new Error("Not implemented")}if(n.id=this.nextObjectId.value++,n.position=new ObjectPosition(this.tiles,this.tileOccupation),n.isUnit()?n.position.subCell=0:n.isBuilding()&&n.position.setCenterOffset(n.getFoundationCenterOffset()),n.isTechno()&&((n.rules.primary||n.rules.secondary||n.rules.weaponCount||n.rules.explodes)&&(n.armedTrait=new ArmedTrait(n,i),n.traits.add(n.armedTrait)),-1!==n.rules.ammo&&(e=n.rules.initialAmmo,n.ammoTrait=new AmmoTrait(n.rules.ammo,-1!==e?e:void 0),n.traits.add(n.ammoTrait)),n.unitOrderTrait=new UnitOrderTrait(n),n.traits.addToFront(n.unitOrderTrait),(n.primaryWeapon||n.secondaryWeapon)&&(n.attackTrait=new AttackTrait(this.tiles,this.tileOccupation),n.traits.add(n.attackTrait)),(n.isInfantry()||n.isVehicle())&&n.rules.deployer&&(n.deployerTrait=new DeployerTrait(n),n.traits.add(n.deployerTrait)),(n.isInfantry()||n.isVehicle())&&n.rules.canDisguise&&(n.disguiseTrait=new DisguiseTrait,n.traits.add(n.disguiseTrait)),n.rules.cloakable&&(n.cloakableTrait=new CloakableTrait(n,i.general.cloakDelay),n.traits.add(n.cloakableTrait)),n.rules.sensors&&(n.sensorsTrait=new SensorsTrait,n.traits.add(n.sensorsTrait)),n.autoRepairTrait=new AutoRepairTrait(!n.isBuilding()),n.traits.add(n.autoRepairTrait),n.rules.trainable&&(n.veteranTrait=new VeteranTrait(n,i.general.veteran),n.traits.add(n.veteranTrait)),n.rules.selfHealing&&n.traits.add(new SelfHealingTrait),n.invulnerableTrait=new InvulnerableTrait,n.traits.add(n.invulnerableTrait),n.warpedOutTrait=new WarpedOutTrait(n),n.traits.add(n.warpedOutTrait),n.temporalTrait=new TemporalTrait(n),n.traits.add(n.temporalTrait),n.rules.bombable&&!n.art.toOverlay&&(n.tntChargeTrait=new TntChargeTrait,n.traits.add(n.tntChargeTrait)),n.rules.immuneToPsionics||n.isBuilding()||(n.mindControllableTrait=new MindControllableTrait(n),n.traits.add(n.mindControllableTrait)),[n.primaryWeapon,n.secondaryWeapon].some(e=>e?.warhead.rules.mindControl)&&(n.mindControllerTrait=new MindControllerTrait(n),n.traits.add(n.mindControllerTrait)),n.rules.spawns&&(n.airSpawnTrait=new AirSpawnTrait,n.traits.add(n.airSpawnTrait)),n.rules.maxDebris&&n.traits.add(new SpawnDebrisTrait)),n.isTechno()||n.isOverlay()||n.isTerrain()){var o=n.isOverlay()&&BridgeOverlayTypes.isBridge(i.getOverlayId(n.name));let e=n.rules.strength;!e&&n.isTerrain()&&(e=i.general.treeStrength),o&&(e=i.combatDamage.bridgeStrength),(e||n.isTechno())&&(n.healthTrait=new HealthTrait(e,n,i.audioVisual.conditionYellow,i.audioVisual.conditionRed),n.traits.add(n.healthTrait)),n.isOverlay()&&o&&(n.bridgeTrait=new BridgeTrait(this.bridges),n.traits.add(n.bridgeTrait),BridgeOverlayTypes.getOverlayBridgeType(i.getOverlayId(n.name))===OverlayBridgeType.Concrete&&n.traits.add(new SpawnDebrisTrait))}return!n.isOverlay()||void 0!==(o=OreOverlayTypes.getOverlayTibType(i.getOverlayId(n.name)))&&(o=i.getTiberium(o),n.traits.add(new TiberiumTrait(n,o))),n.isTerrain()&&n.rules.spawnsTiberium&&n.traits.add(new TiberiumTreeTrait(n.rules)),n.cachedTraits.tick.push(...n.traits.filter(NotifyTick_NotifyTick)),n}}class World{constructor(){this.allObjects=new Map,this._onObjectSpawned=new EventDispatcher,this._onObjectRemoved=new EventDispatcher}get onObjectSpawned(){return this._onObjectSpawned.asEvent()}get onObjectRemoved(){return this._onObjectRemoved.asEvent()}spawnObject(e){if(this.allObjects.has(e.id))throw new Error("Trying to add an already existing object");this.allObjects.set(e.id,e),this._onObjectSpawned.dispatch(this,e)}removeObject(e){if(!this.allObjects.has(e.id))throw new Error("Trying to remove non-existent object");this.allObjects.delete(e.id),this._onObjectRemoved.dispatch(this,e)}hasObjectId(e){return this.allObjects.has(e)}getObjectById(e){if(!this.allObjects.has(e))throw new Error(`Object with id ${e} doesn't exist`);return this.allObjects.get(e)}getAllObjects(){return[...this.allObjects.values()]}}class Node{constructor(e,t){this.id=e,this.data=t,this.neighbors=new Set}addLink(e){this.neighbors.add(e),e!==this&&e.neighbors.add(this)}removeLink(e){this.neighbors.delete(e),e.neighbors.delete(this)}deleteLinks(){for(var e of this.neighbors)e.neighbors.delete(this);this.neighbors.clear()}}class Graph{constructor(){this.nodes=new Map}addNode(e,t){let i=this.getNode(e);return i?i.data=t:i=new Node(e,t),this.nodes.set(e,i),i}removeNode(e){let t=this.getNode(e);return!!t&&(t.deleteLinks(),this.nodes.delete(e),!0)}hasNode(e){return this.nodes.has(e)}getNode(e){return this.nodes.get(e)}getNodeCount(){return this.nodes.size}forEachNode(e){for(var t of this.nodes.values())e(t)}clear(){for(var e of this.nodes.values())e.deleteLinks();this.nodes.clear()}}class NodeHeap{constructor(e=[]){if(this.data=e,this.length=e.length,0<this.length)for(let e=this.length>>1;0<=e;e--)this.down(e);for(let e=0;e<this.length;++e)this.setNodeId(this.data[e],e)}compare(e,t){return e.fScore-t.fScore}setNodeId(e,t){e.heapIndex=t}push(e){this.data.push(e),this.setNodeId(e,this.length),this.length++,this.up(this.length-1)}pop(){if(0!==this.length){var e=this.data[0];return this.length--,0<this.length&&(this.data[0]=this.data[this.length],this.setNodeId(this.data[0],0),this.down(0)),this.data.pop(),e}}peek(){return this.data[0]}updateItem(e){this.down(e),this.up(e)}up(e){let t=this.data;for(var i=t[e];0<e;){var r=e-1>>1,s=t[r];if(0<=this.compare(i,s))break;t[e]=s,this.setNodeId(s,e),e=r}t[e]=i,this.setNodeId(i,e)}down(i){let r=this.data;for(var e=this.length>>1,s=r[i];i<e;){let e=1+(i<<1);var a=e+1;let t=r[e];if(a<this.length&&this.compare(r[a],t)<0&&(e=a,t=r[a]),0<=this.compare(t,s))break;r[i]=t,this.setNodeId(t,i),i=e}r[i]=s,this.setNodeId(s,i)}}class NodeSearchState{constructor(e){this.node=e,this.closed=!1,this.open=0,this.distanceToSource=Number.POSITIVE_INFINITY,this.fScore=Number.POSITIVE_INFINITY,this.heapIndex=-1}}function makeSearchStatePool(){let i=0,r=[];return{createNewState(e){let t=r[i];return t?(t.node=e,t.parent=void 0,t.closed=!1,t.open=0,t.distanceToSource=Number.POSITIVE_INFINITY,t.fScore=Number.POSITIVE_INFINITY,t.heapIndex=-1):(t=new NodeSearchState(e),r[i]=t),i++,t},reset(){i=0}}}function blindHeuristic(){return 0}function constantDistance(){return 1}function PathFinder(d,e={}){let u=e.bestEffort,p=e.maxExpandedNodes||Number.POSITIVE_INFINITY,g=e.heuristic??blindHeuristic,m=e.distance??constantDistance,y=e.excludedNodes,T=makeSearchStatePool();return{find:function(e,t){let i=d.getNode(e);if(!i)throw new Error("fromId is not defined in this graph: "+e);let r=d.getNode(t);if(!r)throw new Error("toId is not defined in this graph: "+t);if(i===r)return[];T.reset();let s=new Map,a=new NodeHeap,n=T.createNewState(i);if(s.set(e,n),n.fScore=y?.(r.data)?Number.POSITIVE_INFINITY:g(i,r),!Number.isFinite(n.fScore)&&i.neighbors.has(r))return[];n.distanceToSource=0,a.push(n),n.open=1;let o,l=n,h=0;for(;0<a.length;){if(o=a.pop(),o.node===r)return reconstructPath(o);if(h++,h>p)break;o.closed=!0,o.node.neighbors.forEach(c)}return u?reconstructPath(l):[];function c(e){let t=s.get(e.id);t||(t=T.createNewState(e),s.set(e.id,t)),t.closed||(0===t.open&&(a.push(t),t.open=1),(e=y?.(e.data)?Number.POSITIVE_INFINITY:o.distanceToSource+m(o.node,e))>=t.distanceToSource||(t.parent=o,t.distanceToSource=e,y?.(r.data)?t.fScore=Number.POSITIVE_INFINITY:t.fScore=e+g(t.node,r,t),t.fScore-t.distanceToSource<l.fScore-l.distanceToSource&&(l=t),a.updateItem(t.heapIndex)))}}}}function reconstructPath(e){let t=[e.node],i=e.parent;for(;i;)t.push(i.node),i=i.parent;return t}function distance(e,t){var i=Math.abs(e.data.tile.rx-t.data.tile.rx),t=Math.abs(e.data.tile.ry-t.data.tile.ry);return i+t+(Math.SQRT2-2)*Math.min(i,t)}function heuristic(e,t,i){var r=Math.abs(e.data.tile.rx-t.data.tile.rx),t=Math.abs(e.data.tile.ry-t.data.tile.ry);let s=r+t+(Math.SQRT2-2)*Math.min(r,t);return i?.parent&&(t=(r=i.parent.node).data.tile.rx-e.data.tile.rx,e=r.data.tile.ry-e.data.tile.ry,i.dirX=t,i.dirY=e,t===i.parent.dirX&&e===i.parent.dirY||(s+=.2)),s}class map_Terrain_Terrain{constructor(e,t,i,r,s){this.tiles=e,this.theaterType=t,this.mapBounds=i,this.tileOccupation=r,this.rules=s,this.passabilityGraphs=new Map,this.invalidatedTiles=new Map,this.tiberiumMayChangePassability=new Set,this.handleTileOccupationUpdate=({tiles:e,object:r})=>{e=e.filter(e=>{if(r.isOverlay()){if(r.isBridge())return!0;if(r.isTiberium()){var t=getLandType(e.terrainType);if(this.tiberiumMayChangePassability.has(t))return!0}}var i=SpeedType.Foot,t=!r.isTerrain();return this.isBlockerObject(r,e,!1,i,t)||r.isBuilding()&&r.rules.leaveRubble});e.length&&this.invalidateTiles(e)},this.handleMapBoundsResize=()=>{this.passabilityGraphs.clear()},r.onChange.subscribe(this.handleTileOccupationUpdate),i.onLocalResize.subscribe(this.handleMapBoundsResize),this.tiberiumMayChangePassability.clear();let a=this.rules.getLandRules(LandType.Tiberium);for(var n of Object.values(SpeedType).filter(e=>"string"!=typeof e)){var o,l=Boolean(Math.sign(a.getSpeedModifier(n)));for(o of Object.values(LandType).filter(e=>"string"!=typeof e))Boolean(Math.sign(this.rules.getLandRules(o).getSpeedModifier(n)))!==l&&this.tiberiumMayChangePassability.add(o)}}getGraphKey(e,t){return e+"_"+Number(t)}invalidateTiles(i){i.length&&[...this.passabilityGraphs.keys()].forEach(e=>{let t=this.invalidatedTiles.get(e);t?i.forEach(e=>t.add(e)):this.invalidatedTiles.set(e,new Set(i))})}computePath(s,a,e,t,i,r,{maxExpandedNodes:n=Number.POSITIVE_INFINITY,bestEffort:o=!0,excludeTiles:l,ignoredBlockers:h=[]}={}){let c=this.computePassabilityGraph(s,a);var d=h.map(e=>this.tileOccupation.calculateTilesForGameObject(e.tile,e)).reduce((e,t)=>e.concat(t),[]);d.length&&this.updatePassability(d,s,a,c,h);var u=this.getNodeId(e,t),p=!!c.hasNode(u);p||this.updatePassability([e],s,a,c,h,1);var g=this.getNodeId(i,r),m=!!c.hasNode(g);let y;var T=p&&!d.length;if(T){let i=this.getIslandIdMap(s,a),r=i.get(e,t);y=(e,t)=>i.get(e,t)===r}else y=(e,t)=>0<this.getPassableSpeed(e,s,a,t,h);if(!m||!y(i,r)){var f=T?15:5,f=o?new RadialTileFinder(this.tiles,this.mapBounds,i,{width:1,height:1},1,f,e=>y(e,!1)&&Math.abs(e.z-i.z)<2&&!l?.({tile:e,onBridge:void 0})).getNextTile():void 0;if(f)i=f,r=!1;else{if(T)return d.length&&this.updatePassability(d,s,a,c),[];c.addNode(g,{tile:i,onBridge:void 0}),n=Math.min(n,500)}}let v=PathFinder(c,{bestEffort:o,maxExpandedNodes:n,excludedNodes:l,distance:distance,heuristic:heuristic}),b=v.find(this.getNodeId(e,t),this.getNodeId(i,r)).map(e=>({tile:e.data.tile,onBridge:e.data.onBridge}));return(b.length<2||l&&b.length&&(!o&&b[0].tile!==i||b[b.length-1].tile!==e))&&(b=[]),p||(c.removeNode(u),this.updatePassability([e],s,a,c)),m||c.removeNode(g),d.length&&this.updatePassability(d,s,a,c),b}computeAllPassabilityGraphs(){Object.keys(SpeedType).forEach(e=>{e=Number(e);isNaN(e)||e===SpeedType.Winged||(this.computePassabilityGraph(e,!1),this.computePassabilityGraph(e,!0))})}computePassabilityGraph(t,i){var r=this.getGraphKey(t,i);let s=this.passabilityGraphs.get(r);if(s){let e=this.invalidatedTiles.get(r);e?.size&&(this.updatePassability([...e],t,i,s),e.clear(),this.computeIslandIds(s))}else s=new Graph,this.passabilityGraphs.set(r,s),this.tiles.forEach(e=>{this.computePassability(e,t,i,s)}),this.computeIslandIds(s);return s}updatePassability(t,i,r,s,a=[],n){let o=new Set;t.forEach(e=>{[e,this.tiles.getNeighbourTile(e,TileDirection.Right),this.tiles.getNeighbourTile(e,TileDirection.BottomRight),this.tiles.getNeighbourTile(e,TileDirection.Bottom),this.tiles.getNeighbourTile(e,TileDirection.BottomLeft)].filter(isNotNullOrUndefined).forEach(e=>o.add(e))});let l=new Map;t.forEach(e=>{var t;for(t of[s.getNode(this.getNodeId(e,!1)),s.getNode(this.getNodeId(e,!0))])t&&(l.set(t.id,t.data.islandId),s.removeNode(t.id))}),o.forEach(e=>{this.computePassability(e,i,r,s,a,n&&t.includes(e)?n:void 0)}),l.forEach((e,t)=>{let i=s.getNode(t);i&&(i.data.islandId=e)})}computePassability(e,t,i,r,s=[],a){var n=[TileDirection.Left,TileDirection.TopLeft,TileDirection.Top,TileDirection.TopRight];if(a||this.getPassableSpeed(e,t,i,!1,s)){var o,l=this.getNodeId(e,!1);r.hasNode(l)||r.addNode(l,{tile:e,onBridge:void 0,forceLandSpeed:a});for(o of n)this.connectTiles(e,void 0,o,t,i,r,s)}var h=this.tileOccupation.getBridgeOnTile(e);if(h&&(a||this.getPassableSpeed(e,t,i,!0,s))){var c,l=this.getNodeId(e,!0);r.hasNode(l)||r.addNode(l,{tile:e,onBridge:h,forceLandSpeed:a});for(c of n)this.connectTiles(e,h,c,t,i,r,s)}}connectTiles(i,r,s,a,n,o,l=[]){var h=this.tiles.getNeighbourTile(i,s);if(h){let e=this.tileOccupation.getBridgeOnTile(h);s=r||e?0:1;if(Math.abs(i.z+(r?.tileElevation??0)-(h.z+(e?.tileElevation??0)))>s){if(!e?.isHighBridge()&&!r?.isHighBridge()||0!==Math.abs(i.z-h.z)||!o.hasNode(this.getNodeId(i,!1)))return;r=e=void 0}s=this.getNodeId(h,!!e);let t=o.getNode(s);this.getPassableSpeed(h,a,n,!!e,l,void 0,t?.data.forceLandSpeed)&&(t=t??o.addNode(s,{tile:h,onBridge:e}),r=this.getNodeId(i,!!r),o.getNode(r).addLink(t))}}getNodeId(e,t){return e.id+(t?"_bridge":"")}computeIslandIds(e){let t=1;e.forEachNode(e=>{e.data.islandId=void 0}),e.forEachNode(e=>{e.data.islandId||this.floodIslandId(e,t++)})}floodIslandId(e,t){let i=[e];for(;i.length;){let e=i.pop();e.data.islandId=t;for(var r of e.neighbors)r.data.islandId||i.push(r)}}getIslandIdMap(e,t){let i=this.computePassabilityGraph(e,t);return{get:(e,t)=>{t=this.getNodeId(e,t);return i.getNode(t)?.data.islandId}}}getPassableSpeed(e,t,i,r,s=[],a=!1,n){if(!this.mapBounds.isWithinBounds(e))return 0;let o=r?e.onBridgeLandType:e.landType;if(void 0===o)return 0;o===LandType.Wall&&t===SpeedType.Track&&(o=getLandType(e.terrainType));let l=this.rules.getLandRules(o);var h,n=n||l.getSpeedModifier(t);if(!n)return 0;if(!a)for(h of this.tileOccupation.getObjectsOnTile(e))if(this.isBlockerObject(h,e,r,t,i)&&!s.includes(h))return 0;return n}isBlockerObject(t,i,e,r,s){if(t.rules.crushable&&[SpeedType.Track,SpeedType.Hover].includes(r))return!1;if(t.isTerrain())return!s||t.rules.getOccupationBits(this.theaterType)===OccupationBits.All;if(t.isBuilding()){if(t.rules.invisibleInGame)return!1;if(t.isDestroyed&&t.rules.leaveRubble)return!1;if(t.rules.gate)return!1;r=t.art.foundation;let e=t.rules.numberImpassableRows;return s?e=r.width:t.rules.weaponsFactory&&!e&&(e=r.width-1),rectContainsPoint({x:t.tile.rx,y:t.tile.ry,width:(e||r.width)-1,height:r.height-1},{x:i.rx,y:i.ry})}return!(t.isAircraft()||t.isInfantry()||t.isVehicle()||t.isSmudge()||t.isOverlay()&&(e&&t.isBridge()||!e&&t.isHighBridge()||t.isTiberium()||t.rules.crate||t.isBridgePlaceholder()))}findObstacles(t,e){var i,r,s=e.rules.speedType,a=e.isInfantry();let n=[];for(i of this.tileOccupation.getGroundObjectsOnTile(t.tile))i!==e&&(((r=this.isBlockerObject(i,t.tile,!!t.onBridge,s,a))||i.isUnit()&&(i.tile===t.tile&&i.onBridge===!!t.onBridge||i.moveTrait.reservedPathNodes.find(e=>e.tile===t.tile&&!!e.onBridge==!!t.onBridge))||[SpeedType.Track,SpeedType.Hover].includes(s)&&i.rules.crushable||a&&i.isTerrain()||i.isBuilding()&&i.rules.gate)&&(r={obj:i,static:r},i.isInfantry()&&a?i.position.desiredSubCell===e.position.desiredSubCell&&n.push(r):i.isTerrain()&&a&&!i.rules.getOccupiedSubCells(this.theaterType).includes(e.position.desiredSubCell)||n.push(r)));return n}dispose(){this.tileOccupation.onChange.unsubscribe(this.handleTileOccupationUpdate),this.mapBounds.onLocalResize.unsubscribe(this.handleMapBoundsResize)}}class MapBounds{constructor(){this.mapCutoffHeight=0,this.mapBuildableSize={x:0,y:0,width:0,height:0},this.localSize={x:0,y:0,width:0,height:0},this.fullSize={width:0,height:0},this.clampedFullSize={x:0,y:0,width:0,height:0},this.rawLocalSize={x:0,y:0,width:0,height:0},this._onLocalResize=new EventDispatcher}get onLocalResize(){return this._onLocalResize.asEvent()}fromMapFile(e,t){this.fullSize={width:2*e.fullSize.width,height:2*e.fullSize.height},this.clampedFullSize={x:1,y:2,width:2*(e.fullSize.width-1)-1/Coords.ISO_TILE_SIZE,height:2*(e.fullSize.height-1)+1-1/Coords.ISO_TILE_SIZE},this.mapCutoffHeight=Math.max(9,t.getCutoffTileHeight());t=Math.max(2,e.localSize.x),e={x:t,y:e.localSize.y,width:Math.min(e.fullSize.width-2-t,e.localSize.width),height:e.localSize.height};return this.updateRawLocalSize(e),this}updateRawLocalSize(e){this.rawLocalSize.width&&this.rawLocalSize.height&&!rectContainsRect(e,this.rawLocalSize)?console.warn("New map limits must be outside old limits. Skipping."):rectEquals(e,this.rawLocalSize)||(this.localSize=this.computeLocalSize(e,this.fullSize.height/2,this.mapCutoffHeight),this.rawLocalSize={...e},this.mapBuildableSize={x:this.localSize.x,y:this.localSize.y+4,width:this.localSize.width-2,height:this.localSize.height-8},this._onLocalResize.dispatch(this))}computeLocalSize(e,t,i){return{x:2*e.x,y:2*e.y-4,height:Math.min(2*(e.height+5)-1,2*t-2*(e.y-3)-i),width:2*e.width}}getLocalSize(){return this.localSize}getRawLocalSize(){return this.rawLocalSize}getFullSize(){return this.fullSize}getClampedFullSize(){return this.clampedFullSize}isWithinBounds(e){return rectContainsPoint(this.mapBuildableSize,{x:e.dx,y:e.dy-e.z})}clampWithinBounds(e){let{x:t,y:i}=rectClampPoint(this.mapBuildableSize,{x:e.dx,y:e.dy-e.z});return i+=t%2-i%2,i>this.mapBuildableSize.y+this.mapBuildableSize.height&&(i-=2),{dx:t,dy:i}}isWithinHardBounds(e){var t=e.x/Coords.LEPTONS_PER_TILE,i=(e.z??e.y)/Coords.LEPTONS_PER_TILE,e=t-i+this.fullSize.width/2-1,i=t+i-this.fullSize.width/2-1;return rectContainsPoint(this.clampedFullSize,{x:++e,y:++i})}}class DirectionalTileFinder{constructor(e,t,i,r,s,a,n,o=()=>!0,l=!0){this.tiles=e,this.mapBounds=t,this.startTile=i,this.maxDistance=s,this.dirX=a,this.dirY=n,this.predicate=o,this.checkBounds=l,this.finished=!1,this.distance=r}getNextTile(){if(!this.finished){let t;do{let e={x:this.startTile.rx,y:this.startTile.ry};e.x+=this.distance*Math.sign(this.dirX),e.y+=this.distance*Math.sign(this.dirY);var i=this.tiles.getByMapCoords(e.x,e.y);if(i&&(!this.checkBounds||this.mapBounds.isWithinBounds(i))&&this.predicate(i)&&(t=i),this.maxDistance&&this.distance>=this.maxDistance)return this.finished=!0,t}while(this.distance++,!t);return t}}}!function(e){e[e.None=0]="None",e[e.Start=1]="Start",e[e.End=2]="End"}(BridgeHeadType=BridgeHeadType||{});class Bridges{constructor(e,t,i,r,s){this.tileSets=e,this.tiles=t,this.tileOccupation=i,this.mapBounds=r,this.rules=s,this.pieces=new Set,this.piecesByTile=new Map,this.handleTileOccupationUpdate=({object:t,type:i})=>{if(t.isOverlay()&&t.isBridge()){var r=t.tile;let e=this.piecesByTile.get(r);if("added"===i){if(e)throw new Error(`A bridge piece already exists at tile (${r.rx},${r.ry})`);var s=this.findBridgeAdjacentTiles(t);e={obj:t,prev:void 0,next:void 0,headType:this.computeHead(t,s.prev,s.next)},this.piecesByTile.set(r,e),this.pieces.add(e),this.connectPiece(e,s.prev,s.next),this.updateOverlayData(e),e.prev&&this.updateOverlayData(e.prev),e.next&&this.updateOverlayData(e.next)}else{if(!e)throw new Error(`Bridge piece was alredy removed at tile (${r.rx},${r.ry})`);t=e.prev,s=e.next;this.disconnectPiece(e),this.piecesByTile.delete(r),this.pieces.delete(e),t&&this.updateOverlayData(t),s&&this.updateOverlayData(s)}}},i.onChange.subscribe(this.handleTileOccupationUpdate)}getPieceAtTile(e){return this.piecesByTile.get(e)}handlePieceHealthChange(e){this.updateOverlayData(e),e.prev&&this.updateOverlayData(e.prev),e.next&&this.updateOverlayData(e.next)}findDominoPieces(t){let i=[],r=!1,e=t.next;if(t.headType===BridgeHeadType.None||e)for(;e;){if(i.push(e),e.headType!==BridgeHeadType.None){r=!0;break}e=e.next}else r=!0;if(r){r=!1,i.length=0;let e=t.prev;if(t.headType===BridgeHeadType.None||e)for(;e;){if(i.push(e),e.headType!==BridgeHeadType.None){r=!0;break}e=e.prev}else r=!0;if(r)return[]}return i}findBridgeAdjacentTiles(e){var t=e.isXBridge(),t=new Vector2(Number(t),Number(!t));let i=new Vector2(e.tile.rx,e.tile.ry);e=i.clone().sub(t),e=this.tiles.getByMapCoords(e.x,e.y),t=i.clone().add(t);return{prev:e,next:this.tiles.getByMapCoords(t.x,t.y)}}connectPiece(e,t,i){t&&(e.prev=this.getPieceAtTile(t),e.prev&&(e.prev.next=e)),i&&(e.next=this.getPieceAtTile(i),e.next&&(e.next.prev=e))}disconnectPiece(e){e.next&&(e.next.prev=void 0,e.next=void 0),e.prev&&(e.prev.next=void 0,e.prev=void 0)}computeHead(e,t,i){var r=e.tile;if(e.isHighBridge()){r=r.z+e.tileElevation;return t?.z===r?BridgeHeadType.Start:i?.z===r?BridgeHeadType.End:BridgeHeadType.None}return BridgeOverlayTypes.isLowBridgeHead(e.overlayId)?BridgeOverlayTypes.isLowBridgeHeadStart(e.overlayId)?BridgeHeadType.Start:BridgeHeadType.End:BridgeHeadType.None}updateOverlayData(t){let i=t.obj,r=t.prev,s=t.next,a=!1;var n=i.isXBridge(),o=BridgeOverlayTypes.getOverlayBridgeType(i.overlayId);if(BridgeOverlayTypes.isLowBridgeHead(i.overlayId)){let e=0;BridgeOverlayTypes.isLowBridgeHeadStart(i.overlayId)?(e=n?20:22,s||e++):(e=n?18:24,r||e++),i.overlayId=(o===OverlayBridgeType.Wood?BridgeOverlayTypes.minLowBridgeWoodId:BridgeOverlayTypes.minLowBridgeConcreteId)+e,i.value=e,a=!0}else{let e;var l,h=(i.healthTrait?.health??100)<=50;e=t.headType!==BridgeHeadType.None?t.headType===BridgeHeadType.Start?s?h?6:(s.obj.healthTrait?.health??100)<=50?5:0:n?8:7:r?h?6:(r.obj.healthTrait?.health??100)<=50?4:0:n?7:8:(n||(l=r,r=s,s=l),r||s?r?s?(t=(r.obj.healthTrait?.health??100)<=50,l=(s.obj.healthTrait?.health??100)<=50,h||t&&l?6:t?4:l?5:0):8:7:0),n||(e+=9),i.isHighBridge()?i.value=e:(i.overlayId=(o===OverlayBridgeType.Wood?BridgeOverlayTypes.minLowBridgeWoodId:BridgeOverlayTypes.minLowBridgeConcreteId)+e,i.value=e,a=!0)}a&&(i.name=this.rules.getOverlayName(i.overlayId))}findClosestBridgeSpec(i){let e=new RadialTileFinder(this.tiles,this.mapBounds,i,{width:1,height:1},1,3,e=>{if(e.z!==i.z)return!1;let t=this.tileOccupation.getBridgeOnTile(e);return!(!t?.isLowBridge()||this.getPieceAtTile(t.tile)?.headType===BridgeHeadType.None)||!!this.tileSets.isHighBridgeBoundaryTile(e.tileNum)},!1);var o=e.getNextTile();if(o){let r,t,s,a;var l=!this.tileOccupation.getBridgeOnTile(o);let e;if(l){var h=this.findHighBridgeBoundary(o);if(!h)return;r=h.tile,t=OverlayBridgeType.Concrete,this.tileSets.getSetNum(o.tileNum)===this.tileSets.getGeneralValue("WoodBridgeSet")&&(t=OverlayBridgeType.Wood),s=h.headType===HighBridgeHeadType.TopLeft||h.headType===HighBridgeHeadType.BottomRight,a=h.headType===HighBridgeHeadType.TopLeft||h.headType===HighBridgeHeadType.TopRight,e=h.headType}else{r=this.tileOccupation.getBridgeOnTile(o).tile;let e=this.getPieceAtTile(r);if(!e)throw new Error("Bridge head is not defined");var c=BridgeOverlayTypes.getOverlayBridgeType(e.obj.overlayId);if(c===OverlayBridgeType.NotBridge)throw new Error("Expected a bridge type");t=c,s=e.obj.isXBridge(),a=e.headType===BridgeHeadType.Start}var d=Number(s)*(a?1:-1),u=Number(!s)*(a?1:-1);let n;if(l){o=new DirectionalTileFinder(this.tiles,this.mapBounds,r,1,100,d,u,e=>e.z===r.z&&this.tileSets.isHighBridgeBoundaryTile(e.tileNum),!1).getNextTile(),c=this.tileSets.getSetNum(r.tileNum);if(!o||this.tileSets.getSetNum(o.tileNum)!==c)return;o=this.findHighBridgeBoundary(o);if(!o)return;if(e!==this.tileSets.getOppositeHighBridgeHeadType(o.headType))return;n=o.tile}else{let t,i=1;for(var p=r.rx,g=r.ry;!t;){var m=this.tiles.getByMapCoords(p+d*i,g+u*i);if(!m)return;let e=this.getPieceAtTile(m);if(e&&e.obj.isXBridge()!==s)return;e?.headType===(a?BridgeHeadType.End:BridgeHeadType.Start)&&(t=e),i++}n=t.obj.tile}return{start:a?r:n,end:a?n:r,type:t,isHigh:l,isXBridge:s}}}findHighBridgeBoundary(e){let t=this.tileSets.getTile(e.tileNum);var s=this.tileSets.getHighBridgeHeadType(t.index);if(void 0!==s){let i=0,r=0;switch(s){case HighBridgeHeadType.TopLeft:i=1,r=0;break;case HighBridgeHeadType.BottomRight:i=-1,r=0;break;case HighBridgeHeadType.TopRight:i=0,r=1;break;case HighBridgeHeadType.BottomLeft:i=0,r=-1;break;case HighBridgeHeadType.MiddleTlBr:i=1,r=0;break;case HighBridgeHeadType.MiddleTrBl:i=0,r=1;break;default:throw new Error(`Unhandled head type "${s}"`)}const h=t.getRelativeTilePositions();var a=h.filter(e=>4===e.z).sort((e,t)=>100*(i?i*(t.rx-e.rx):r*(t.ry-e.ry))+(i?e.ry-t.ry:e.rx-t.rx))[0].subTile,n=h[a].rx-h[e.subTile].rx,o=h[a].ry-h[e.subTile].ry,l=this.tiles.getByMapCoords(e.rx+n,e.ry+o);if(l){if(l.subTile===a&&l.tileNum===e.tileNum)return{tile:l,headType:s};console.warn("Found invalid bridge boundary tile. "+`(${e.rx},${e.ry})+(${n},${o})`)}}else console.warn(`Couldn't find a valid bridge type for index "${t.index}" @ ${e.rx},`+e.ry)}canBeRepaired(i){let e=this.createBridgePieceTileFinder(i,e=>!(this.getPieceAtTile(e)||this.tileSets.isHighBridgeMiddleTile(e.tileNum)&&e.z===i.start.z)),r=!1,s;for(var a=i.start.rx!==i.end.rx?TileDirection.BottomLeft:TileDirection.BottomRight;s=e.getNextTile();){r=!0;let e=this.tiles.getNeighbourTile(s,a),t=this.tiles.getNeighbourTile(e,a);if(i.isHigh){if([s,e,t].find(e=>this.tileOccupation.getGroundObjectsOnTile(e).some(e=>e.isBuilding()&&!e.rules.invisibleInGame)))return!1}else if([s,e,t].find(e=>this.tileOccupation.getGroundObjectsOnTile(e).some(e=>!(e.isUnit()||e.isSmudge()||e.isOverlay()&&e.isBridgePlaceholder()))))return!1}return r}getPieceTiles(e){var t=e.obj.tile,i=e.obj.isXBridge()?TileDirection.BottomLeft:TileDirection.BottomRight,e=this.tiles.getNeighbourTile(t,i);return[t,e,this.tiles.getNeighbourTile(e,i)]}findMapHighBridgeHeadTiles(){var e,t=this.tiles.getAllBridgeSetTiles();let i=new Set;for(e of t){var r=this.findHighBridgeBoundary(e);r&&i.add(r.tile)}return i}findBridgeSpecsForHeadTiles(e){let t=new Map;for(var i of e){i=this.findClosestBridgeSpec(i);i&&t.set(i.start.id+":"+i.end.id,i)}return[...t.values()]}findAllBridgeTiles(e){let t=[];var i,r=e.start.rx!==e.end.rx?TileDirection.BottomLeft:TileDirection.BottomRight;for(i of this.findNonBuildablePieceTiles(e)){var s=this.tiles.getNeighbourTile(i,r),a=this.tiles.getNeighbourTile(s,r);t.push(i,s,a)}return t}getBridgeSize(e){var t=e.start.rx!==e.end.rx;return{width:t?e.end.rx-e.start.rx+1:3,height:t?3:e.end.ry-e.start.ry+1}}findBridgePieces(e){let t=this.createBridgePieceTileFinder(e,e=>!!this.getPieceAtTile(e)),i=[];for(var r;r=t.getNextTile();)i.push(this.getPieceAtTile(r));return i}findDestroyedPieceTiles(t){let e=this.createBridgePieceTileFinder(t,e=>!(this.getPieceAtTile(e)||this.tileSets.isHighBridgeMiddleTile(e.tileNum)&&e.z===t.start.z)),i=[];for(var r;r=e.getNextTile();)i.push(r);return i}findNonBuildablePieceTiles(t){let e=this.createBridgePieceTileFinder(t,e=>!(this.tileSets.isHighBridgeMiddleTile(e.tileNum)&&e.z===t.start.z)),i=[];for(var r;r=e.getNextTile();)i.push(r);return i}createBridgePieceTileFinder(e,t){var i=e.start.rx!==e.end.rx;return new DirectionalTileFinder(this.tiles,this.mapBounds,e.start,1,(i?e.end.rx-e.start.rx:e.end.ry-e.start.ry)-1,Number(i),Number(!i),t,!1)}dispose(){this.pieces.forEach(e=>{e.prev=void 0,e.next=void 0}),this.tileOccupation.onChange.unsubscribe(this.handleTileOccupationUpdate)}}var AllianceStatus,SelectionLevel,NotifySpawn_NotifySpawn,NotifyUnspawn_NotifyUnspawn,NotifyOwnerChange_NotifyOwnerChange,NotifyAllianceChange,NotifyDestroy_NotifyDestroy,AllianceEventType,QuadTree_THREE=__webpack_require__(70);const tmpVec2=new QuadTree_THREE.Vector2;class QuadTree{constructor(e,t){this.box=e,this.config=t,this.parentMap=new Map,this.objects=[]}add(e,t=!0){var i=this.config.getKey(e);if(this.box.containsPoint(i)){if(!this.regions)return this.parentMap.get(e)?.remove(e),this.parentMap.set(e,this),this.objects.push({key:i,value:e}),t&&this.update(),!0;for(var r of this.regions)if(r.add(e,t))return!0}return!1}remove(t,e=!0){let i=this.parentMap.get(t);i&&(i===this?(this.parentMap.delete(t),this.objects.splice(this.objects.findIndex(e=>e.value===t),1),e&&this.parent?.update()):i.remove(t,e))}updateObject(t){let i=this.parentMap.get(t);if(i){var e=this.config.getKey(t);if(i.box.containsPoint(e))i.objects.find(e=>e.value===t).key=e;else{i.remove(t,!1);let e=i.parent;for(;e&&!e.add(t,!1);)e=e.parent}}}queryRange(e,t=[]){if(this.box.intersectsBox(e))if(this.regions)for(var i of this.regions)i.queryRange(e,t);else for(var r of this.objects)e.containsPoint(r.key)&&t.push(r.value);return t}update(){let e=0;if(this.regions){for(var t of this.regions)e+=t.update();e<=this.config.joinThreshold&&this.join()}else e=this.objects.length,e>=this.config.splitThreshold&&this.split()&&this.update();return e}split(){if(this.regions||this.config.maxDepth<=1)return!1;var t,e,i={getKey:this.config.getKey,joinThreshold:this.config.joinThreshold,splitThreshold:this.config.splitThreshold,maxDepth:this.config.maxDepth-1},r=this.generateRegions(),s=this.objects;this.objects=[],this.regions=[];for(t of r){let e=new QuadTree(t,i);e.parentMap=this.parentMap,this.regions.push(e),e.parent=this}for(e of s)this.parentMap.delete(e.value),this.add(e.value,!1);return!0}join(){if(!this.regions)return!1;for(var e of this.regions){e.join(),e.parent=void 0;for(var t of e.objects)this.objects.push(t),this.parentMap.set(t.value,this)}return!(this.regions=void 0)}generateRegions(){let i=[this.box.clone()];var r=this.box.getCenter(tmpVec2);let s=i[0],a=s.clone();s.max.x=r.x,a.min.x=r.x,i.push(a);for(let e=0,t=i.length;e<t;e++)s=i[e],a=s.clone(),s.max.y=r.y,a.min.y=r.y,i.push(a);return i}}class TileOcclusion{constructor(e){this.tiles=e,this.tileOcclusion=[];let t=this.tileOcclusion;for(var i of e.getAll())t[i.rx]=t[i.rx]||[],t[i.rx][i.ry]=new Set}addOccluder(t){let e=this.calculateTilesForGameObject(t);e.forEach(e=>this.occludeTile(e,t))}removeOccluder(t){let e=this.calculateTilesForGameObject(t);e.forEach(e=>this.unoccludeTile(e,t))}calculateTilesForGameObject(e){var t=e.art.occupyHeight,i=Math.max(0,t-2);let r=[];var s=e.getFoundation();for(let t=1;t<=i;t++)for(let e=0;e<s.width;e++)r.push(new Vector2(e-t,-t));for(let t=1;t<=i;t++)for(let e=1;e<s.height;e++)r.push(new Vector2(-t,e-t));r.push(...e.art.addOccupy);for(let{x:t,y:i}of e.art.removeOccupy){var a=r.findIndex(e=>e.x===t&&e.y===i);-1!==a&&r.splice(a,1)}var n,o,l=e.tile;let h=[];for({x:n,y:o}of r){var c=this.tiles.getByMapCoords(l.rx+n,l.ry+o);c&&h.push(c)}return h}occludeTile(e,t){this.tileOcclusion[e.rx][e.ry].add(t),e.occluded=!0}unoccludeTile(e,t){let i=this.tileOcclusion[e.rx][e.ry];i.delete(t),e.occluded=0<i.size}isTileOccluded(e){return 0<this.tileOcclusion[e.rx][e.ry].size}}class AutoLat{static calculate(d,u){let p=new Map;d.forEach(e=>{var t=u.getSetNum(e.tileNum);p.set(e,t),u.isCLAT(t)&&(t=u.getLAT(t),p.set(e,t),e.tileNum=u.getTileNumFromSet(t))}),d.forEach(t=>{var i=p.get(t);if(u.isLAT(i)){let e=0;var r=d.getNeighbourTile(t,TileDirection.TopRight),s=d.getNeighbourTile(t,TileDirection.BottomRight),a=d.getNeighbourTile(t,TileDirection.BottomLeft),n=d.getNeighbourTile(t,TileDirection.TopLeft);r&&u.canConnectTiles(i,p.get(r))&&(e+=1),s&&u.canConnectTiles(i,p.get(s))&&(e+=2),a&&u.canConnectTiles(i,p.get(a))&&(e+=4),n&&u.canConnectTiles(i,p.get(n))&&(e+=8),0<e&&(n=u.getCLATSet(i),t.tileNum=u.getTileNumFromSet(n,e))}else if(i===u.getGeneralValue("RampBase")&&!(t.rampType<1||4<t.terrainType)){let e=-1;var o=d.getNeighbourTile(t,TileDirection.TopRight),l=d.getNeighbourTile(t,TileDirection.BottomRight),h=d.getNeighbourTile(t,TileDirection.BottomLeft),c=d.getNeighbourTile(t,TileDirection.TopLeft);switch(t.rampType){case 1:c&&0===c.rampType&&e++,l&&0===l.rampType&&(e+=2);break;case 2:o&&0===o.rampType&&e++,h&&0===h.rampType&&(e+=2);break;case 3:l&&0===l.rampType&&e++,c&&0===c.rampType&&(e+=2);break;case 4:h&&0===h.rampType&&e++,o&&0===o.rampType&&(e+=2)}-1!==e&&(t.tileNum=u.getTileNumFromSet(u.getGeneralValue("RampSmooth"),3*(t.rampType-1)+e))}})}}class GameMap{get startingLocations(){return this.mapFile.startingLocations}constructor(e,t,i,r){this.mapFile=e,this.tiles=new TileCollection(this.mapFile.tiles,t,i.general,r),this.mapBounds=(new MapBounds).fromMapFile(this.mapFile,this.tiles),this.tileOccupation=new TileOccupation(this.tiles),this.tileOcclusion=new TileOcclusion(this.tiles),this.terrain=new map_Terrain_Terrain(this.tiles,this.mapFile.theaterType,this.mapBounds,this.tileOccupation,i),this.bridges=new Bridges(t,this.tiles,this.tileOccupation,this.mapBounds,i);let s=this.mapFile.tags;for(let t of this.mapFile.cellTags){let e=this.tiles.getByMapCoords(t.coords.x,t.coords.y);e&&(e.tag=s.find(e=>e.id===t.tagId))}r=this.tiles.getMapSize(),i=Math.max(r.width,r.height)/5;this.technosByTile=new QuadTree(new Box2(new Vector2(0,0),new Vector2(r.width,r.height)),{getKey:e=>{e=e.isBuilding()?e.centerTile:e.tile;return new Vector2(e.rx,e.ry)},maxDepth:this.computeQuadDepth(i),splitThreshold:10,joinThreshold:5}),this.mapFile.theaterType!==TheaterType.Snow&&AutoLat.calculate(this.tiles,t)}computeQuadDepth(e){if(e<=1)return 1;let t=0;for(;1<=e/2;)e/=2,t++;return t+(1<e?1:0)}getLighting(){return this.mapFile.lighting}getIonLighting(){return this.mapFile.ionLighting}getTheaterType(){return this.mapFile.theaterType}getTags(){return this.mapFile.tags}getTriggers(){return this.mapFile.triggers}getCellTags(){return this.mapFile.cellTags}getVariables(){return this.mapFile.variables}getWaypoint(t){return this.mapFile.waypoints.find(e=>e.number===t)}getTileAtWaypoint(e){e=this.getWaypoint(e);if(e){e=this.tiles.getByMapCoords(e.rx,e.ry);if(e)return e}}isWithinBounds(e){return this.mapBounds.isWithinBounds(e)}clampWithinBounds(e){var t=this.mapBounds.clampWithinBounds(e);let i=this.tiles.getByDisplayCoords(t.dx,t.dy);if(i&&this.mapBounds.isWithinBounds(i)){let e=i,t=i.z;for(;0<=t&&e&&this.mapBounds.isWithinBounds(e);)i=e,e=this.tiles.getByDisplayCoords(e.dx,e.dy+2),t-=2}else{let e=0;for(;!i||!this.mapBounds.isWithinBounds(i);){if(30<e)throw new Error("Exceeded max elevation while trying to clamp tile to map bounds");i=this.tiles.getByDisplayCoords(t.dx,t.dy+e),e+=2}}return i}isWithinHardBounds(e){return this.mapBounds.isWithinHardBounds(e)}getInitialMapObjects(){return{terrains:this.mapFile.terrains,overlays:this.mapFile.overlays,smudges:this.mapFile.smudges,technos:[...this.mapFile.structures,...this.mapFile.infantries,...this.mapFile.vehicles,...this.mapFile.aircrafts]}}getObjectsOnTile(e){return this.tileOccupation.getObjectsOnTile(e)}getGroundObjectsOnTile(e){return this.tileOccupation.getGroundObjectsOnTile(e)}getTileZone(e,t=!1){return this.tileOccupation.getTileZone(e,t)}dispose(){this.terrain.dispose(),this.bridges.dispose()}}class PlayerPair{constructor(e,t){this.first=e,this.second=t}has(e){return this.first===e||this.second===e}equals(e){return this.first===e.first&&this.second===e.second||this.first===e.second&&this.second===e.first}}!function(e){e[e.Requested=0]="Requested",e[e.Formed=1]="Formed"}(AllianceStatus=AllianceStatus||{});class Alliances{constructor(e){this.playerList=e,this.alliances=[]}findByPlayers(e,t){let i=new PlayerPair(e,t);return this.alliances.find(e=>e.players.equals(i))}filterByPlayer(t){return this.alliances.filter(e=>e.players.first===t||e.players.second===t)}request(e,t){if(!this.canRequestAlliance(t))throw new Error(`Player ${t.name} is not a human combatant.`);if(this.canFormAlliance(e,t)){if(this.findByPlayers(e,t))throw new Error("Can't request alliance because an alliance is already pending or formed between "+`${e.name} and ${t.name}.`);return this.setAlliance(e,t,AllianceStatus.Requested)}}cancelRequest(e,t){var i=this.findByPlayers(e,t);if(!i||i.status!==AllianceStatus.Requested)throw new Error(`There is no pending alliance request for player ${t.name} from player `+e.name);if(i.players.first!==e)throw new Error(`Can't cancel request initiated by the other player (${t.name})`);this.alliances.splice(this.alliances.indexOf(i),1)}acceptRequest(t,i){if(this.canFormAlliance(t,i)){let e=this.findByPlayers(t,i);if(!e||e.status!==AllianceStatus.Requested)throw new Error(`There is no pending alliance request for player ${i.name} from player `+t.name);if(e.players.first!==t)throw new Error("Can't accept own alliance request for player "+i.name);e.status=AllianceStatus.Formed}}setAlliance(e,t,i){if(!this.canFormAlliance(e,t))throw new Error(`Can't form alliance between players "${e.name}" and "${t.name}"`);var r;if(r=this.findByPlayers(e,t))throw new Error(`An alliance already exists between players ${e.name} and `+t.name);return r={players:new PlayerPair(e,t),status:i},this.alliances.push(r),r}breakAlliance(e,t){var i=this.findByPlayers(e,t);if(!i||i.status!==AllianceStatus.Formed)throw new Error(`There is no alliance between player ${e.name} and player `+t.name);this.alliances.splice(this.alliances.indexOf(i),1)}areAllied(e,t){t=this.findByPlayers(e,t);return!!t&&t.status===AllianceStatus.Formed}getAllies(t){return this.filterByPlayer(t).filter(e=>e.status===AllianceStatus.Formed).map(e=>e.players.first===t?e.players.second:e.players.first)}haveSharedIntel(e,t){return e.isObserver||t.isObserver||e===t||this.areAllied(e,t)}canRequestAlliance(e){return e.isCombatant()&&!e.isAi}canFormAlliance(t,i){let e=this.getHostilePlayers();if(0===e.filter(e=>e.has(t)&&!e.has(i)).length)return!1;if(0===e.filter(e=>e.has(i)&&!e.has(t)).length)return!1;let r=new PlayerPair(t,i);return!!e.filter(e=>!e.equals(r)).length}getHostilePlayers(){var i,r=this.playerList.getCombatants();let s=[];for(let t=0;t<r.length;t++)for(let e=t+1;e<r.length;e++)this.getAllies(r[t]).includes(r[e])||(i=new PlayerPair(r[t],r[e]),s.push(i));return s}getHash(){return fnv32a(this.alliances.map(e=>[this.playerList.getPlayerNumber(e.players.first),this.playerList.getPlayerNumber(e.players.second),e.status]).flat())}debugGetState(){return this.alliances.map(e=>({first:e.players.first,second:e.players.second,status:e.status}))}}class PlayerList{constructor(){this.players=[]}addPlayer(e){this.players.push(e)}getPlayerAt(e){if(e>=this.players.length)throw new RangeError(`Player #${e} out of bounds`);return this.players[e]}getPlayerByName(t){var e=this.players.find(e=>e.name===t);if(!e)throw new Error(`Player with name "${t}" not found`);return e}getPlayerNumber(e){var t=this.players.indexOf(e);if(-1===t)throw new Error(`Player ${e.name} not found`);return t}getCombatants(){return this.players.filter(e=>e.isCombatant())}getNonNeutral(){return this.players.filter(e=>!e.isNeutral)}getCivilian(){return this.players.find(e=>e.country?.side===SideType.Civilian)}getAll(){return this.players}}!function(e){e[e.None=0]="None",e[e.Hover=1]="Hover",e[e.Selected=2]="Selected",e[e.SelectedHover=3]="SelectedHover"}(SelectionLevel=SelectionLevel||{});class SelectionModel{constructor(e){this.selectionLevel=SelectionLevel.None,e.isBuilding()&&e.rules.wall?this.maxSelectionLevel=SelectionLevel.None:this.maxSelectionLevel=e.rules.selectable?SelectionLevel.Selected|SelectionLevel.Hover:SelectionLevel.Hover}getSelectionLevel(){return this.selectionLevel}setSelectionLevel(e){this.selectionLevel=Math.min(this.maxSelectionLevel,e)}setHover(e){this.setSelectionLevel(e?this.selectionLevel|SelectionLevel.Hover:this.selectionLevel&~SelectionLevel.Hover)}setSelected(e){this.setSelectionLevel(e?this.selectionLevel|SelectionLevel.Selected:this.selectionLevel&~SelectionLevel.Selected)}isHovered(){return this.selectionLevel>>SelectionLevel.Hover&1}isSelected(){return this.selectionLevel>=SelectionLevel.Selected}getControlGroupNumber(){return this.controlGroupNumber}setControlGroupNumber(e){this.controlGroupNumber=e}}class UnitSelection{constructor(){this.selectedUnits=new Set,this.selectionModelsByUnit=new Map,this.groups=new Map,this.hashNeedsUpdate=!0}getOrCreateSelectionModel(e){let t=this.selectionModelsByUnit.get(e);return t||(t=new SelectionModel(e),this.selectionModelsByUnit.set(e,t)),t}deselectAll(){this.selectedUnits.forEach(e=>this.selectionModelsByUnit.get(e)?.setSelected(!1)),this.selectedUnits.clear(),this.hashNeedsUpdate=!0}addToSelection(e){this.selectedUnits.add(e),this.getOrCreateSelectionModel(e).setSelected(!0),this.hashNeedsUpdate=!0}removeFromSelection(e){e.forEach(e=>{this.selectedUnits.delete(e),this.getOrCreateSelectionModel(e).setSelected(!1)}),this.hashNeedsUpdate=!0}getSelectedUnits(){return[...this.selectedUnits].filter(e=>!e.isDestroyed&&!e.isCrashing&&!e.isDisposed&&e.isSpawned)}isSelected(e){return this.selectedUnits.has(e)}cleanupUnit(e){this.selectionModelsByUnit.delete(e),this.selectedUnits.delete(e),this.removeUnitsFromGroup([e]),this.hashNeedsUpdate=!0}updateHash(){this.hash=fnv32a([...this.selectedUnits].map(e=>e.id))}getHash(){return this.hashNeedsUpdate&&(this.updateHash(),this.hashNeedsUpdate=!1),this.hash}createGroup(e){this.addUnitsToGroup(e,this.getSelectedUnits())}addUnitsToGroup(e,t,i=!0){this.removeUnitsFromGroup(t);let r=this.groups.get(e);r||(r=new Set,this.groups.set(e,r)),i&&([...r.values()].forEach(e=>this.selectionModelsByUnit.get(e)?.setControlGroupNumber(void 0)),r.clear());for(var s of t)r.add(s),this.getOrCreateSelectionModel(s).setControlGroupNumber(e)}addGroupToSelection(e){if(this.groups.has(e))for(var t of[...this.groups.get(e)])this.addToSelection(t)}selectGroup(e){this.deselectAll(),this.addGroupToSelection(e)}getGroupUnits(e){return[...this.groups.get(e)??[]]}removeUnitsFromGroup(e){for(var t of this.groups.values())for(var i of e)t.delete(i),this.selectionModelsByUnit.get(i)?.setControlGroupNumber(void 0)}}class BoxedVar{constructor(e){this._onChange=new EventDispatcher,this.value=e}get value(){return this._value}set value(e){var t=e!==this._value;this._value=e,t&&this._onChange.dispatch(this,e)}get onChange(){return this._onChange.asEvent()}}class Player{get credits(){return this._credits}set credits(e){if(e<0)throw new RangeError("Can't set credits to a negative value");this._credits=e}constructor(e,t=void 0,i,r=new Color(255,0,0)){this.name=e,this.country=t,this.startLocation=i,this.color=r,this.isAi=!1,this.defeated=!1,this.resigned=!1,this.dropped=!1,this.objectsByType=new Map,this.objectsById=new Map,this.traits=new Traits,this._credits=0,this.score=0,this.limitedUnitsBuiltByName=new Map,this.unitsBuiltByType=new Map,this.unitsKilledByType=new Map,this.unitsLostByType=new Map,this.buildingsCaptured=0,this.cratesPickedUp=0,this.creditsGained=0,this.cheerCooldownTicks=0,this.isObserver=!t,this.isNeutral=!!t&&!t.isPlayable()}getOrCreateObjectsForType(e){let t=this.objectsByType.get(e);return t||(t=new Set,this.objectsByType.set(e,t)),t}addOwnedObject(e){let t=this.getOrCreateObjectsForType(e.type);t.add(e),(e.owner=this).objectsById.set(e.id,e)}removeOwnedObject(e){let t=this.objectsByType.get(e.type);if(!t||!t.has(e))throw new Error(`GameObject ${e.name} does not belong to player `+this.name);t.delete(e),this.objectsById.delete(e.id)}getOwnedObjectById(e){return this.objectsById.get(e)}getOwnedObjectsByType(e,t=!1){let i=[];return i=[...this.objectsByType.get(e)||new Set],t||(i=i.filter(e=>!e.limboData)),i}getOwnedObjects(e=!1){let t=[];return[...this.objectsByType.values()].forEach(e=>{e.forEach(e=>t.push(e))}),e||(t=t.filter(e=>!e.limboData)),t}removeAllOwnedObjects(){this.objectsByType.forEach(e=>e.clear()),this.objectsById.clear()}get buildings(){return this.getOrCreateObjectsForType(ObjectType.Building)}addUnitsBuilt(e,t){this.unitsBuiltByType.set(e.type,(this.unitsBuiltByType.get(e.type)??0)+t),e.buildLimit<0&&this.limitedUnitsBuiltByName.set(e.name,(this.limitedUnitsBuiltByName.get(e.name)??0)+t)}getUnitsBuilt(e){return void 0!==e?this.unitsBuiltByType.get(e)??0:[...this.unitsBuiltByType.values()].reduce((e,t)=>e+t,0)}getLimitedUnitsBuilt(e){return this.limitedUnitsBuiltByName.get(e)??0}addUnitsKilled(e,t){this.unitsKilledByType.set(e,(this.unitsKilledByType.get(e)??0)+t)}getUnitsKilled(e){return void 0!==e?this.unitsKilledByType.get(e)??0:[...this.unitsKilledByType.values()].reduce((e,t)=>e+t,0)}addUnitsLost(e,t){this.unitsLostByType.set(e,(this.unitsLostByType.get(e)??0)+t)}getUnitsLost(e){return void 0!==e?this.unitsLostByType.get(e)??0:[...this.unitsLostByType.values()].reduce((e,t)=>e+t,0)}isCombatant(){return!this.isNeutral&&!this.isObserver&&!this.defeated}canProduceVeteran(e){if(!this.production||!this.country)throw new Error("Non-combatants can't produce units");var t=this.production.getQueueTypeForObject(e),t=this.production.getFactoryTypeForQueueType(t);return this.production.hasVeteranType(t)||this.country.hasVeteranUnit(e.type,e.name)}getHash(){return fnv32a([this.credits,...this.traits.getAll().map(e=>e.getHash?.()??0)])}debugGetState(){return{name:this.name,credits:this.credits,traits:this.traits.getAll().reduce((e,t)=>{var i=t.debugGetState?.();return void 0!==i&&(e[t.constructor.name]=i),e},{})}}dispose(){this.traits.dispose(),this.production?.dispose()}}class RadarTrait{constructor(){this.disabled=!0,this.activeEvents=[]}isDisabled(){return this.disabled}setDisabled(e){this.disabled=e}}const prereqCategIniVals=(new Map).set("POWER",PrereqCategory.Power).set("FACTORY",PrereqCategory.Factory).set("BARRACKS",PrereqCategory.Barracks).set("RADAR",PrereqCategory.Radar).set("TECH",PrereqCategory.Tech).set("PROC",PrereqCategory.Proc);class Production{static factory(e,t,i,r){let s=new Production(e,t.mpDialogSettings.techLevel,i,t,r);t=t.general.maximumQueuedObjects+1;return s.addQueue(QueueType.Structures,new ProductionQueue(QueueType.Structures,1,1)),s.addQueue(QueueType.Armory,new ProductionQueue(QueueType.Armory,1,1)),s.addQueue(QueueType.Infantry,new ProductionQueue(QueueType.Infantry,t,t)),s.addQueue(QueueType.Vehicles,new ProductionQueue(QueueType.Vehicles,t,t)),s.addQueue(QueueType.Ships,new ProductionQueue(QueueType.Ships,t,t)),s.addQueue(QueueType.Aircrafts,new ProductionQueue(QueueType.Aircrafts,0,t)),s}constructor(e,t,i,r,s){this.player=e,this.maxTechLevel=t,this.gameOpts=i,this.rules=r,this.allAvailableObjects=s,this.buildSpeedModifier=1,this.queues=new Map,this._onQueueUpdate=new EventDispatcher,this.primaryFactories=new Map,this.factoryCounts=new Map,this.veteranTypes=new Set,this.stolenTech=new Set}get onQueueUpdate(){return this._onQueueUpdate.asEvent()}addQueue(e,t){this.queues.set(e,t),t.onUpdate.subscribe(()=>this._onQueueUpdate.dispatch(this,t))}getQueue(e){var t=this.queues.get(e);if(!t)throw new Error("No queue found with type "+QueueType[e]);return t}getAllQueues(){return[...this.queues.values()]}getQueueTypeForObject(e){if(e.type===ObjectType.Building)return e.buildCat===BuildCat.Combat?QueueType.Armory:QueueType.Structures;if(e.type===ObjectType.Infantry)return QueueType.Infantry;if(e.type===ObjectType.Vehicle)return e.naval?QueueType.Ships:QueueType.Vehicles;if(e.type===ObjectType.Aircraft)return QueueType.Aircrafts;throw new Error("Unsupported object type "+ObjectType[e.type])}getQueueForObject(e){return this.getQueue(this.getQueueTypeForObject(e))}getQueueTypeForFactory(e){if(e===FactoryType.InfantryType)return QueueType.Infantry;if(e===FactoryType.UnitType)return QueueType.Vehicles;if(e===FactoryType.AircraftType)return QueueType.Aircrafts;if(e===FactoryType.NavalUnitType)return QueueType.Ships;throw new Error("Unsupported factory type "+FactoryType[e])}getFactoryTypeForQueueType(e){if(e===QueueType.Structures||e===QueueType.Armory)return FactoryType.BuildingType;if(e===QueueType.Infantry)return FactoryType.InfantryType;if(e===QueueType.Vehicles)return FactoryType.UnitType;if(e===QueueType.Aircrafts)return FactoryType.AircraftType;if(e===QueueType.Ships)return FactoryType.NavalUnitType;throw new Error("Unsupported queue type "+QueueType[e])}getQueueForFactory(e){return this.getQueue(this.getQueueTypeForFactory(e))}isAvailableForProduction(e){return-1!==e.techLevel&&e.techLevel<=this.maxTechLevel&&!(0===e.buildLimit&&!this.player.isAi)&&!(e.superWeapon&&this.rules.getSuperWeapon(e.superWeapon).disableableFromShell&&!this.gameOpts.superWeapons)&&this.hasFactoryFor(e)&&this.meetsPrerequisites(e)}getAvailableObjects(){return this.allAvailableObjects.filter(e=>this.isAvailableForProduction(e))}hasFactoryFor(i){if(i.owner.length){let t=this.getFactoryTypeFor(i);return!![...this.player.buildings].find(e=>e.factoryTrait?.type===t&&(t!==FactoryType.UnitType||e.rules.naval===i.naval)&&!!e.rules.owner.find(e=>i.owner.includes(e)))}return!0}meetsStolenTech(e){return e.requiresStolenAlliedTech?this.stolenTech.has(SideType.GDI):e.requiresStolenSovietTech?this.stolenTech.has(SideType.Nod):!e.requiresStolenThirdTech||this.stolenTech.has(SideType.ThirdSide)}getFactoryTypeFor(e){return e.type===ObjectType.Building?FactoryType.BuildingType:e.type===ObjectType.Infantry?FactoryType.InfantryType:e.type===ObjectType.Aircraft?FactoryType.AircraftType:e.naval?FactoryType.NavalUnitType:FactoryType.UnitType}meetsPrerequisites(e){let t=[...this.player.buildings].map(e=>e.name);for(var i of e.prerequisiteOverride)if(i=i.toUpperCase(),t.includes(i))return!0;if(!e.isAvailableTo(this.player.country))return!1;var r;for(r of e.prerequisite)if(r=r.toUpperCase(),prereqCategIniVals.has(r)){var s=prereqCategIniVals.get(r);if(void 0===s)throw new Error("Unknown prereqName "+r);var a,n=this.rules.general.prereqCategories.get(s);if(void 0===n)throw new Error(`Missing prerequisite category ${s} in rules`);let e=!1;for(a of n)if(-1!==t.indexOf(a)){e=!0;break}if(!e)return!1}else if(-1===t.indexOf(r))return!1;return!!this.meetsStolenTech(e)}getPrimaryFactory(e){return this.primaryFactories.get(e)}setPrimaryFactory(e){e.rules.factory&&this.primaryFactories.set(e.rules.factory,e)}isPrimaryFactory(e){return this.getPrimaryFactory(e.rules.factory)===e}incrementFactoryCount(e){this.factoryCounts.set(e,(this.factoryCounts.get(e)??0)+1)}decrementFactoryCount(e){if(!this.factoryCounts.get(e))throw new Error(`Can't decrement factory count ${FactoryType[e]}. Already 0`);this.factoryCounts.set(e,this.factoryCounts.get(e)-1)}getFactoryCount(e){return this.factoryCounts.get(e)??0}crownPrimaryFactoryHeir(t){var e=[...this.player.buildings].find(e=>e.rules.factory===t);e?this.primaryFactories.set(t,e):this.primaryFactories.delete(t)}hasAnyFactory(){return 0<this.primaryFactories.size}addVeteranType(e){this.veteranTypes.add(e)}hasVeteranType(e){return this.veteranTypes.has(e)}addStolenTech(e){this.stolenTech.add(e)}dispose(){this.queues.clear(),this.player=void 0}}class SuperWeaponsTrait_SuperWeaponsTrait{constructor(){this.superWeapons=new Map}getAll(){return[...this.superWeapons.values()]}add(e){this.superWeapons.set(e.name,e)}has(e){return this.superWeapons.has(e)}get(e){return this.superWeapons.get(e)}remove(e){this.superWeapons.delete(e)}}class SharedDetectDisguiseTrait{constructor(){this.objects=new Set}add(e){this.objects.add(e)}delete(e){this.objects.delete(e)}has(e){return this.objects.has(e)}dispose(){this.objects.clear()}}class PlayerFactory{constructor(e,t,i){this.rules=e,this.gameOpts=t,this.allAvailableObjects=i}createCombatant(e,t,i,r,s,a){let n=new Player(e,t,i,r);return n.isAi=s,n.aiDifficulty=a,n.powerTrait=new PowerTrait(n),n.traits.add(n.powerTrait),n.radarTrait=new RadarTrait,n.traits.add(n.radarTrait),n.superWeaponsTrait=new SuperWeaponsTrait_SuperWeaponsTrait,n.traits.add(n.superWeaponsTrait),n.production=Production.factory(n,this.rules,this.gameOpts,this.allAvailableObjects),n.sharedDetectDisguiseTrait=new SharedDetectDisguiseTrait,n}createObserver(e,t){let i=new Player(e,void 0,void 0,t.colors.get("LightGrey"));return i.radarTrait=new RadarTrait,i.traits.add(i.radarTrait),i.radarTrait.setDisabled(!1),i}createNeutral(e,t){var i=[...e.countryRules.values()].find(e=>e.side===SideType.Civilian);if(!i)throw new Error("Missing neutral country. No country found in rules with Civilian side");i=new Country(i);let r=new Player(t,i,void 0,e.colors.get("LightGrey"));return r.powerTrait=new PowerTrait(r),r.traits.add(r.powerTrait),r}}(NotifySpawn_NotifySpawn=NotifySpawn_NotifySpawn||{}).onSpawn=Symbol(),(NotifyUnspawn_NotifyUnspawn=NotifyUnspawn_NotifyUnspawn||{}).onUnspawn=Symbol(),(NotifyOwnerChange_NotifyOwnerChange=NotifyOwnerChange_NotifyOwnerChange||{}).onChange=Symbol();class PowerTrait_PowerTrait{[NotifySpawn_NotifySpawn.onSpawn](e,t){e.isTechno()&&e.rules.power&&!this.isCapturablePower(e,e.owner)&&e.owner.powerTrait?.updateFrom(e,"add",t)}[NotifyUnspawn_NotifyUnspawn.onUnspawn](e,t){e.isTechno()&&e.rules.power&&!e.warpedOutTrait.isActive()&&!this.isCapturablePower(e,e.owner)&&e.owner.powerTrait?.updateFrom(e,"remove",t)}[NotifyHealthChange.onChange](e,t){e.isTechno()&&e.rules.power&&!e.warpedOutTrait.isActive()&&!this.isCapturablePower(e,e.owner)&&e.owner.powerTrait?.updateFrom(e,"update",t)}[NotifyOwnerChange_NotifyOwnerChange.onChange](e,t,i){e.rules.power&&!e.warpedOutTrait.isActive()&&(this.isCapturablePower(e,t)||t.powerTrait?.updateFrom(e,"remove",i),this.isCapturablePower(e,e.owner)||e.owner.powerTrait?.updateFrom(e,"add",i))}[NotifyWarpChange.onChange](e,t,i){e.rules.power&&!this.isCapturablePower(e,e.owner)&&e.owner.powerTrait?.updateFrom(e,i?"remove":"add",t)}[NotifyTick.onTick](e){for(var t of e.getCombatants())t.powerTrait.updateBlackout(e)}isCapturablePower(e,t){return 0<e.rules.power&&t.isNeutral&&e.rules.needsEngineer}}class ObjectSellEvent{constructor(e){this.target=e,this.type=EventType.ObjectSell}}class SellTrait{constructor(e,t){this.game=e,this.generalRules=t}sell(t){if(!t.isBuilding()||!t.rules.unsellable){let e=this.computeRefundValue(t);e&&(t.rules.wall&&(e=0),t.traits.filter(NotifySell).forEach(e=>{e[NotifySell.onSell](t,this.game)}),t.isBuilding()?this.game.getConstructionWorker(t.owner).unplace(t,()=>this.afterObjectUnspawned(t,e)):(this.game.unspawnObject(t),this.afterObjectUnspawned(t,e)))}}afterObjectUnspawned(e,t){e.owner.credits+=t,this.game.events.dispatch(new ObjectSellEvent(e)),e.dispose()}computeRefundValue(e){let t=0;return 0<e.rules.soylent?t=e.rules.soylent:e.rules.cost&&(t=e.purchaseValue,e.owner.isAi||(t=Math.floor(t*this.generalRules.refundPercent))),t}computePurchaseValue(e,t){return e.cost}dispose(){this.game=void 0}}class RadarOnOffEvent{constructor(e,t){this.target=e,this.radarEnabled=t,this.type=EventType.RadarOnOff}}class RadarEvent{constructor(e,t,i){this.target=e,this.radarEventType=t,this.tile=i,this.type=EventType.RadarEvent}}class RadarTrait_RadarTrait{constructor(){this.activeLightningStrikes=new Map}[NotifySpawn_NotifySpawn.onSpawn](e,t){e.isBuilding()&&e.rules.radar&&this.updateRadarForPlayer(e.owner,t)}[NotifyUnspawn_NotifyUnspawn.onUnspawn](e,t){e.isBuilding()&&e.rules.radar&&this.updateRadarForPlayer(e.owner,t)}[NotifyPower.onPowerLow](e,t){this.updateRadarForPlayer(e,t)}[NotifyPower.onPowerRestore](e,t){this.updateRadarForPlayer(e,t)}[NotifyPower.onPowerChange](){}[NotifyOwnerChange_NotifyOwnerChange.onChange](e,t,i){e.rules.radar&&(this.updateRadarForPlayer(t,i),this.updateRadarForPlayer(e.owner,i))}[NotifyWarpChange.onChange](e,t){e.rules.radar&&this.updateRadarForPlayer(e.owner,t)}[NotifySuperWeaponActivate.onActivate](e,t,i){if(e===SuperWeaponType.LightningStorm){this.activeLightningStrikes.set(t,(this.activeLightningStrikes.get(t)??0)+1);for(var r of i.getCombatants())r===t||i.alliances.areAllied(r,t)||this.updateRadarForPlayer(r,i)}}[NotifySuperWeaponDeactivate.onDeactivate](e,t,i){if(e===SuperWeaponType.LightningStorm){e=(this.activeLightningStrikes.get(t)??0)-1;if(0<e?this.activeLightningStrikes.set(t,e):this.activeLightningStrikes.delete(t),e<=0)for(var r of i.getCombatants())this.updateRadarForPlayer(r,i)}}updateRadarForPlayer(i,r){var e,t;i.radarTrait&&(e=i.radarTrait?.isDisabled(),t=![...i.buildings].find(e=>e.rules.radar&&!e.warpedOutTrait.isActive())||i.powerTrait.level===PowerLevel.Low||[...this.activeLightningStrikes.entries()].some(([e,t])=>t&&e!==i&&!r.alliances.areAllied(e,i)),i.radarTrait.setDisabled(t),e!==t&&r.events.dispatch(new RadarOnOffEvent(i,!t)))}[NotifyAttack_NotifyAttack.onAttack](e,t,i){e.isTechno()&&(!e.isBuilding()||e.rules.canBeOccupied||e.rules.needsEngineer?e.isVehicle()&&e.harvesterTrait&&this.addEventForPlayer(RadarEventType.HarvesterUnderAttack,e.owner,e.tile,i):this.addEventForPlayer(RadarEventType.BaseUnderAttack,e.owner,e.tile,i))}addEventForPlayer(r,e,s,a){let n=e.radarTrait;if(n){let t=a.rules.general.radar;n.activeEvents=n.activeEvents.filter(e=>a.currentTick-e.startTick<t.getEventDuration(e.type));let i=new RangeHelper(a.map.tileOccupation);!!n.activeEvents.find(e=>e.type===r&&i.isInTileRange(s,e.tile,0,t.getEventSuppresionDistance(e.type)))||(n.activeEvents.push({startTick:a.currentTick,tile:s,type:r}),a.events.dispatch(new RadarEvent(e,r,s)))}}}class InsufficientFundsEvent{constructor(e){this.target=e,this.type=EventType.InsufficientFunds}}const SIDEBAR_CLOCK_FRAMES=55;class ProductionTrait{constructor(e,t){this.rules=e,this.speedCheat=t,this.availableObjectRules=new Set;t=60*e.general.buildSpeed*GameSpeed.BASE_TICKS_PER_SECOND;this.baseBuildSpeed=1/(t/1e3),[...e.buildingRules.values(),...e.infantryRules.values(),...e.vehicleRules.values(),...e.aircraftRules.values()].forEach(e=>{e.owner.length&&this.availableObjectRules.add(e)})}[NotifyTick.onTick](e){for(var t of e.getCombatants())for(var i of t.production.getAllQueues())this.tickQueue(i,t,e)}[NotifySpawn_NotifySpawn.onSpawn](e,t){var i;e.isBuilding()&&e.owner.production?(i=e.rules.factory)&&(e.owner.production.getPrimaryFactory(i)||e.owner.production.setPrimaryFactory(e),e.owner.production.incrementFactoryCount(i),i===FactoryType.AircraftType&&this.updateAircraftQueueMaxSize(e.owner,t)):e.isAircraft()&&e.owner.production&&this.rules.general.padAircraft.includes(e.name)&&this.updateAircraftQueueMaxSize(e.owner,t)}[NotifyUnspawn_NotifyUnspawn.onUnspawn](e,t){var i;e.isBuilding()&&e.owner.production?(this.ensurePrerequisites(e.owner),(i=e.rules.factory)&&(e.owner.production.getPrimaryFactory(i)===e&&e.owner.production.crownPrimaryFactoryHeir(i),e.owner.production.decrementFactoryCount(i),i===FactoryType.AircraftType&&this.updateAircraftQueueMaxSize(e.owner,t))):e.isAircraft()&&e.owner.production&&this.rules.general.padAircraft.includes(e.name)&&this.updateAircraftQueueMaxSize(e.owner,t)}[NotifyOwnerChange_NotifyOwnerChange.onChange](e,t,i){var r;e.isBuilding()?(this.ensurePrerequisites(t),(r=e.rules.factory)&&(t.production?.getPrimaryFactory(r)===e&&t.production.crownPrimaryFactoryHeir(r),e.owner.production&&!e.owner.production.getPrimaryFactory(r)&&e.owner.production.setPrimaryFactory(e),t.production?.decrementFactoryCount(r),e.owner.production?.incrementFactoryCount(r),r===FactoryType.AircraftType&&(this.updateAircraftQueueMaxSize(e.owner,i),this.updateAircraftQueueMaxSize(t,i)))):e.isAircraft()&&this.rules.general.padAircraft.includes(e.name)&&(this.updateAircraftQueueMaxSize(e.owner,i),this.updateAircraftQueueMaxSize(t,i))}[NotifyPower.onPowerLow](e){e.production&&(e.production.buildSpeedModifier=this.computeLowPowerBuildSpeedModifier(e.powerTrait.power,e.powerTrait.drain))}[NotifyPower.onPowerRestore](e){e.production&&(e.production.buildSpeedModifier=1)}[NotifyPower.onPowerChange](e){e.powerTrait?.level===PowerLevel.Low&&e.production&&(e.production.buildSpeedModifier=this.computeLowPowerBuildSpeedModifier(e.powerTrait.power,e.powerTrait.drain))}computeLowPowerBuildSpeedModifier(e,t){e=1-Math.min(1,e/t),t=this.rules.general;return clamp(1-.3*t.lowPowerPenaltyModifier*e/.15,t.minLowPowerProductionSpeed,t.maxLowPowerProductionSpeed)}updateAircraftQueueMaxSize(i,r){i.production&&r.afterTick(()=>{var e=[...i.buildings].filter(e=>e.helipadTrait).reduce((e,t)=>e+t.dockTrait.numberOfDocks,0),t=i.getOwnedObjectsByType(ObjectType.Aircraft,!0).filter(e=>r.rules.general.padAircraft.includes(e.name)).length;i.production.getQueueForFactory(FactoryType.AircraftType).maxSize=Math.max(0,e-t)})}tickQueue(i,r,s){if(i.status===QueueStatus.Active){let e=!1,t=i.getFirst();var a,n=r.production.getFactoryTypeForQueueType(i.type),o=r.production.getFactoryCount(n),l=r.production.buildSpeedModifier,h=1/GameMath.pow(this.rules.general.multipleFactory,o-1),n=t.rules.wall?1/this.rules.general.wallBuildSpeedCoefficient:1,o=this.baseBuildSpeed*l*h*n,l=t.creditsEach,h=SIDEBAR_CLOCK_FRAMES-1,n=l&&!this.speedCheat.value?floorTo(l/o*t.rules.buildTimeMultiplier,h):h,n=Math.max(h,n),o=r.credits,h=t.creditsEach-t.creditsSpent,h=Math.min(r.credits,l/n+t.creditsSpentLeftover,h);0<h?(a=Math.floor(h),t.creditsSpentLeftover=h-a,a&&(t.creditsSpent+=a,t.progress=t.creditsSpent/t.creditsEach,r.credits-=a,e=!0)):t.creditsEach||(a=t.progress*n,t.progress=Math.min(1,(1+a)/n),e=!0),e&&1===t.progress&&(i.status=QueueStatus.Ready),0<o&&!r.credits&&s.events.dispatch(new InsufficientFundsEvent(r)),e&&i.notifyUpdated()}}ensurePrerequisites(e){if(e.production)for(var t of e.production.getAllQueues()){var i;for(i of t.getAll().map(e=>({rules:e.rules,quantity:e.quantity,creditsSpent:e.creditsSpent})))e.production.isAvailableForProduction(i.rules)||(t.pop(i.rules,i.quantity),e.credits+=i.creditsSpent)}}getAvailableObjects(){return[...this.availableObjectRules]}}(NotifyAllianceChange=NotifyAllianceChange||{}).onChange=Symbol();class MapShroudTrait{constructor(e,t){this.map=e,this.alliances=t,this.shroudByPlayer=new Map,this.revealedToAll=new Set,this.gapGenerators=new Set,this.handleTileOccupationUpdate=({object:e,type:t})=>{if("removed"!==t&&e.isTechno()){var i,t=e.owner;for(i of[t,...this.alliances.getAllies(t)])this.shroudByPlayer.get(i)?.revealFrom(e)}}}getPlayerShroud(e){return this.shroudByPlayer.get(e)}init(t){t.map.tileOccupation.onChange.subscribe(this.handleTileOccupationUpdate);let i=(new MapShroud).fromTiles(this.map.tiles);for(var r of t.getCombatants()){let e=i.clone();this.shroudByPlayer.set(r,e),this.revealObjects(e,r,t),e.update()}}[NotifyElevationChange.onElevationChange](e,t,i){if(Math.floor(e.tileElevation)!==Math.floor(i)){var r,i=e.owner;for(r of[i,...this.alliances.getAllies(i)])this.shroudByPlayer.get(r)?.revealFrom(e)}}[NotifyTick.onTick](e){for(var[t,i]of this.shroudByPlayer)t.defeated&&!t.isObserver?this.shroudByPlayer.delete(t):i.update()}[NotifyOwnerChange_NotifyOwnerChange.onChange](e,t,i){if(e.isBuilding()&&e.rules.spySat&&(this.revealMap(e.owner,i),t.getOwnedObjectsByType(ObjectType.Building).find(e=>e.rules.spySat)||this.resetShroud(t,i)),e.isSpawned)for(var r of[e.owner,...i.alliances.getAllies(e.owner)])this.shroudByPlayer.get(r)?.revealFrom(e)}[NotifyAllianceChange.onChange](t,e,i){if(e){let e=this.getPlayerShroud(t.players.first);var r,s,t=i.alliances.getAllies(t.players.first).map(e=>this.getPlayerShroud(e)).filter(isNotNullOrUndefined);for(r of t)e.merge(r);e.invalidateFull();for(s of t)s.copy(e),s.invalidateFull()}}[NotifySpawn_NotifySpawn.onSpawn](e,t){if(e.isBuilding()){if(e.rules.spySat&&this.revealMap(e.owner,t),e.rules.revealToAll){this.revealedToAll.add(e);for(var i of t.getCombatants())i===e.owner||t.alliances.areAllied(e.owner,i)||(this.shroudByPlayer.get(i)?.revealObject(e),t.traits.get(RadarTrait_RadarTrait).addEventForPlayer(RadarEventType.EnemyObjectSensed,i,e.centerTile,t))}e.gapGeneratorTrait&&this.gapGenerators.add(e)}}[NotifyUnspawn_NotifyUnspawn.onUnspawn](e,t){e.isBuilding()&&(e.rules.spySat&&(e.owner.getOwnedObjectsByType(ObjectType.Building).find(e=>e.rules.spySat)||this.resetShroud(e.owner,t)),e.rules.revealToAll&&this.revealedToAll.delete(e),e.gapGeneratorTrait&&this.gapGenerators.delete(e))}[NotifyPower.onPowerLow](e,t){this.updateGaps(t,e)}[NotifyPower.onPowerRestore](e,t){this.updateGaps(t,e)}[NotifyPower.onPowerChange](e,t){}revealMap(e,t){this.shroudByPlayer.get(e)?.revealAll(),this.markOwnGapTiles(t,e),this.updateGaps(t)}resetShroud(e,t){let i=this.shroudByPlayer.get(e);i&&(i.reset(),this.markOwnGapTiles(t,e),this.revealObjects(i,e,t))}revealObjects(t,e,i){var r;for(r of[...e.getOwnedObjects(),...i.alliances.getAllies(e).map(e=>e.getOwnedObjects()).flat()])t.revealFrom(r);this.revealedToAll.forEach(e=>t.revealObject(e))}updateGaps(e,t){for(var i of this.gapGenerators)t&&i.owner!==t||i.gapGeneratorTrait.update(i,e)}markOwnGapTiles(e,t){for(var i of this.gapGenerators)i.owner!==t&&!e.alliances.areAllied(i.owner,t)||this.getPlayerShroud(t)?.toggleFlagsAround(i.tile,i.gapGeneratorTrait.radiusTiles,ShroudFlag.Darken,!0)}dispose(){this.map.tileOccupation.onChange.unsubscribe(this.handleTileOccupationUpdate)}}class PackBuildingTask extends Task{constructor(e){super(),this.game=e}onTick(e){return!(e.buildStatus!==BuildStatus.BuildDown&&(e.setBuildStatus(BuildStatus.BuildDown,this.game),!e.rules.wall))||(this.children.push(new WaitMinutesTask(this.game.rules.general.buildupTime)),!1)}}const isLegacyDisposable=e=>!e.dispose;class CompositeDisposable{constructor(){this.disposables=new Set}add(...e){e.map(e=>this.disposables.add("function"==typeof e?{dispose:e}:e))}remove(...e){e.map(e=>this.disposables.delete(e))}dispose(){this.disposables.forEach(e=>{"function"==typeof e?e():isLegacyDisposable(e)?e.destroy():e.dispose()}),this.disposables.clear()}}class ConstructionWorker{constructor(e,t,i,r,s){this.player=e,this.rules=t,this.art=i,this.map=r,this.game=s,this.adjacencyMaps=new Map,this.disposables=new CompositeDisposable;let a=({object:e})=>{e.isBuilding()&&this.adjacencyMaps.clear()};this.map.tileOccupation.onChange.subscribe(a),this.disposables.add(()=>this.map.tileOccupation.onChange.unsubscribe(a)),this.disposables.add(this.game.events.subscribe(EventType.AllianceChange,()=>this.adjacencyMaps.clear()),this.game.events.subscribe(EventType.ObjectOwnerChange,e=>{e.target.isBuilding()&&this.adjacencyMaps.clear()}),this.game.events.subscribe(EventType.ObjectDestroy,e=>{e.target.isBuilding()&&e.target.rules.leaveRubble&&this.adjacencyMaps.clear()}))}getAdjacentRect(e,t,i){return{x:e.rx-i,y:e.ry-i,width:t.width+2*i,height:t.height+2*i}}getAdjacencyMap(e){var t;let i=[];for(t of[...this.player.buildings,...this.game.gameOpts.buildOffAlly?this.game.alliances.getAllies(this.player).map(e=>[...e.buildings].filter(e=>e.rules.eligibileForAllyBuilding)).flat():[]])t.rules.baseNormal&&i.push(this.getAdjacentRect(t.tile,t.art.foundation,e));return i}meetsAdjacency(e,t){let i=this.adjacencyMaps.get(t);i||(i=this.getAdjacencyMap(t),this.adjacencyMaps.set(t,i));for(var r of i)if(rectIntersect(e,r))return!0;return!1}getPlacementPreview(e,t,i={}){var{normalizedTile:r=!1,ignoreObjects:s,ignoreAdjacent:i=!1}=i,a=this.rules.getBuilding(e),e=this.art.getObject(e,ObjectType.Building);let n=[];var o=e.foundation,l=r?t:this.normalizePlacementTileCoords(e,t);let h=!0;t={x:l.rx,y:l.ry,width:o.width,height:o.height};i||this.meetsAdjacency(t,a.adjacent)||(h=!1);for(let t=0;t<o.width;t++)for(let e=0;e<o.height;e++){var c={x:l.rx+t,y:l.ry+e},d=this.map.tiles.getByMapCoords(c.x,c.y);d&&n.push({rx:c.x,ry:c.y,buildable:h&&this.isTileBuildable(d,a,s)})}if(a.wall&&n[0].buildable){let e=this.getWallConnectingTiles(l,a);e.forEach(e=>{n.push({rx:e.rx,ry:e.ry,buildable:!0})})}return n}canPlaceAt(e,t,i={}){var{normalizedTile:r=!1,ignoreObjects:s,ignoreAdjacent:i=!1}=i,a=this.rules.getBuilding(e),e=this.art.getObject(e,ObjectType.Building),n=e.foundation,o=r?t:this.normalizePlacementTileCoords(e,t),t={x:o.rx,y:o.ry,width:n.width,height:n.height};if(!i&&!this.meetsAdjacency(t,a.adjacent))return!1;for(let t=0;t<n.width;t++)for(let e=0;e<n.height;e++){var l={x:o.rx+t,y:o.ry+e},l=this.map.tiles.getByMapCoords(l.x,l.y);if(!l||!this.isTileBuildable(l,a,s))return!1}return!0}placeAt(e,t,i=!1){let r=[],s=this.rules.getBuilding(e),a=i?t:this.normalizePlacementTile(e,t);if(s.wall){let t=[[a,s]],e=this.getWallConnectingTiles(a,s);e.forEach(e=>{e!==a&&t.push([e,s])});for(var n of t)r.push(this.executePlacement(n[0],n[1]))}else{var o,t=this.executePlacement(a,s);r.push(t);for(o of this.map.tileOccupation.calculateTilesForGameObject(a,t)){var l=this.map.getObjectsOnTile(o).find(e=>e.isSmudge());l&&this.game.unspawnObject(l)}}return r}normalizePlacementTileCoords(e,t){e=e.foundationCenter;return{rx:t.rx-e.x,ry:t.ry-e.y}}normalizePlacementTile(e,t){e=this.art.getObject(e,ObjectType.Building),e=this.normalizePlacementTileCoords(e,t),t=this.map.tiles.getByMapCoords(e.rx,e.ry);if(!t)throw new Error(`Can't build outside map (${e.rx}, ${e.ry})`);return t}unplace(e,t){e.unitOrderTrait.cancelAllTasks(),e.unitOrderTrait.addTasks(new TaskGroup(new PackBuildingTask(this.game),new CallbackTask(()=>{this.game.unspawnObject(e),t()})).setCancellable(!1)),e.unitOrderTrait[NotifyTick_NotifyTick.onTick](e,this.game)}executePlacement(e,t){let i=this.game.createObject(ObjectType.Building,t.name);return this.game.changeObjectOwner(i,this.player),i.purchaseValue=this.game.sellTrait.computePurchaseValue(t,this.player),this.game.spawnObject(i,e),i}getWallConnectingTiles(i,r){var s,a=r.guardRange+1;let n=[];for(s of[[0,1],[0,-1],[1,0],[-1,0]]){let t=[];for(let e=0;e<a;++e){var o={x:i.rx+s[0]*e,y:i.ry+s[1]*e},o=this.map.tiles.getByMapCoords(o.x,o.y);if(!o)break;if(this.map.getObjectsOnTile(o).find(e=>e.isBuilding()&&e.name===r.name&&e.owner===this.player)){n=n.concat(t);break}if(!this.isTileBuildable(o,r))break;t.push(o)}}return n}isTileBuildable(e,t,i){return!!this.map.isWithinBounds(e)&&(!this.game.mapShroudTrait.getPlayerShroud(this.player)?.isShrouded(e)&&(!this.map.getGroundObjectsOnTile(e).some(e=>!(i?.includes(e)||e.isBuilding()&&e.rules.invisibleInGame||e.isSmudge()))&&(t.waterBound?0<this.rules.getLandRules(e.landType).getSpeedModifier(SpeedType.Float):0===e.rampType&&this.rules.getLandRules(e.landType).buildable)))}dispose(){this.disposables.dispose()}}class StartingUnitsGenerator{static generate(e,t,i,r){var s,a=i.reduce((e,t)=>e+t.cost,0)/i.length*e;let n=[],o=a,l=(i=i.filter(e=>e.isAvailableTo(r)&&e.hasOwner(r))).filter(e=>t.includes(e.name));for(s of l){if(o<=0)break;var h=2/3/l.length,h=Math.ceil(h*a/s.cost);o-=h*s.cost,n.push({name:s.name,type:ObjectType.Vehicle,count:h})}var c,i=i.filter(e=>!l.includes(e)),d=o/i.length;for(c of i){if(o<=0)break;var u=Math.ceil(d/c.cost);o-=u*c.cost,n.push({name:c.name,type:ObjectType.Infantry,count:u})}return n}}class GameEventBus{constructor(){this.dispatcher=new EventDispatcher,this.dispatchersByType=new Map}dispatch(e){this.dispatcher.dispatch(void 0,e),this.dispatchersByType.get(e.type)?.dispatch(void 0,e)}subscribe(e,t){let i=void 0,r;return r="function"==typeof e?e:(i=e,t),void 0===i?(this.dispatcher.subscribe(r),()=>this.unsubscribe(r)):this.subscribeType(i,r)}unsubscribe(e,t){let i=void 0,r;r="function"==typeof e?e:(i=e,t),void 0===i?this.dispatcher.unsubscribe(r):this.unsubscribeType(i,r)}subscribeType(e,t){let i=this.dispatchersByType.get(e);return i||(i=new EventDispatcher,this.dispatchersByType.set(e,i)),i.subscribe(t),()=>this.unsubscribeType(e,t)}unsubscribeType(e,t){this.dispatchersByType.get(e)?.unsubscribe(t)}}class ObjectDestroyEvent{constructor(e,t,i){this.target=e,this.attackerInfo=t,this.incidental=i,this.type=EventType.ObjectDestroy}}class PlayerDefeatedEvent{constructor(e){this.target=e,this.type=EventType.PlayerDefeated}}(NotifyDestroy_NotifyDestroy=NotifyDestroy_NotifyDestroy||{}).onDestroy=Symbol();class ObjectOwnerChangeEvent{constructor(e,t){this.target=e,this.prevOwner=t,this.type=EventType.ObjectOwnerChange}}class ObjectUnspawnEvent{constructor(e){this.gameObject=e,this.type=EventType.ObjectUnspawn}}class ObjectSpawnEvent{constructor(e){this.gameObject=e,this.type=EventType.ObjectSpawn}}!function(e){e[e.Requested=0]="Requested",e[e.Formed=1]="Formed",e[e.Broken=2]="Broken"}(AllianceEventType=AllianceEventType||{});class AllianceChangeEvent{constructor(e,t,i){this.alliance=e,this.changeType=t,this.from=i,this.type=EventType.AllianceChange}}var NotifyObjectTraitAdd,GameStatus,ActionType,NotifyPlaceBuilding,PointerType,OrderFeedbackType,EvacState,EnterHospitalTask_State,EnterTransportTask_State,UpdateType,DebugCommandType,mersenne_twister=__webpack_require__(804),mersenne_twister_default=__webpack_require__.n(mersenne_twister);class Prng{static factory(e,t){t=Number.isNaN(Number(e))?Crc32.calculateCrc(binaryStringToUint8Array(e)):Number(e+""+t);return new Prng(t)}constructor(e){this.prng=new(mersenne_twister_default())(e)}generateRandomInt(e,t){var i=this.prng.random();return this.lastRandom=i,Math.floor(i*(t-e+1))+e}generateRandom(){var e=this.prng.random();return this.lastRandom=e}getLastRandom(){return this.lastRandom}}class TriggerExecutor{constructor(e,t){this.action=e,this.trigger=t}getDebugName(){return`${this.action.triggerId}[${this.action.index}] (${this.trigger.name}).`}}class AddSuperWeaponExecutor extends TriggerExecutor{constructor(e,t,i){super(e,t),this.oneTimeOnly=i,this.superWeaponIdx=Number(e.params[1])}execute(i){var r=[...i.rules.superWeaponRules.values()].find(e=>e.index===this.superWeaponIdx);if(r){let t=i.getAllPlayers().find(e=>e.country?.name===this.trigger.houseName);if(t&&t.superWeaponsTrait&&!t.superWeaponsTrait.has(r.name)){let e=i.createSuperWeapon(r.name,t,this.oneTimeOnly);e.isGift=!0,t.superWeaponsTrait.add(e)}}else console.warn(`No superweapon found with index "${this.superWeaponIdx}". `+`Skipping action ${this.getDebugName()}.`)}}class ApplyDamageExecutor extends TriggerExecutor{constructor(e,t,i){super(e,t),this.damage=i}execute(t){var e=Number(this.action.params[1]),i=t.map.getTileAtWaypoint(e);if(i){var r=t.rules.getWarhead(Warhead.HE_WARHEAD_NAME);let e=new Warhead(r);var s=t.map.tileOccupation.getBridgeOnTile(i),a=s?.tileElevation??0,r=t.map.getTileZone(i);e.detonate(t,this.damage,i,a,Coords.tile3dToWorld(i.rx+.5,i.ry+.5,i.z+a),r,s?CollisionType.OnBridge:CollisionType.None,t.createTarget(s,i),void 0)}else console.warn(`No valid location found for waypoint ${e}. `+`Skipping action ${this.getDebugName()}.`)}}class ChangeHouseAllExecutor extends TriggerExecutor{execute(r){let t=r.getAllPlayers().find(e=>e.country?.name===this.trigger.houseName);if(t){let i=Number(this.action.params[1]),e;if(i>=ChangeHouseAllExecutor.locationHouseIdBegin&&i<ChangeHouseAllExecutor.locationHouseIdBegin+r.map.startingLocations.length){let t=i-ChangeHouseAllExecutor.locationHouseIdBegin;e=r.getAllPlayers().find(e=>e.startLocation===t)}else e=r.getAllPlayers().find(e=>e.country?.id===i);if(e?.defeated&&(e=r.isAssetRedistributionEnabled()?r.alliances.getAllies(t)[0]:void 0),e)for(var s of t.getOwnedObjects(!0))r.changeObjectOwner(s,e)}}}ChangeHouseAllExecutor.locationHouseIdBegin=4475;class ChangeHouseExecutor extends TriggerExecutor{constructor(e,t){super(e,t),this.houseId=Number(e.params[1])}execute(e,t){let i;if(this.houseId>=ChangeHouseExecutor.locationHouseIdBegin&&this.houseId<ChangeHouseExecutor.locationHouseIdBegin+e.map.startingLocations.length){let t=this.houseId-ChangeHouseExecutor.locationHouseIdBegin;i=e.getAllPlayers().find(e=>e.startLocation===t)}else i=e.getAllPlayers().find(e=>e.country?.id===this.houseId);if(i?.defeated&&(i=e.isAssetRedistributionEnabled()?e.alliances.getAllies(i)[0]:void 0),i)for(var r of t)r instanceof GameObject&&r.isSpawned&&e.changeObjectOwner(r,i)}}ChangeHouseExecutor.locationHouseIdBegin=4475;class CheerTask extends Task{constructor(){super(),this.executed=!1,this.cancellable=!1}onTick(e){return this.executed?(e.stance=StanceType.None,!0):!e.isInfantry()||!e.art.sequences.has(SequenceType.Cheer)||(e.stance!==StanceType.None&&e.stance!==StanceType.Guard||(e.stance=StanceType.Cheer,this.children.push(new WaitMinutesTask(1/60).setCancellable(!1)),!(this.executed=!0)))}}class CheerExecutor extends TriggerExecutor{constructor(e,t){super(e,t),this.houseId=Number(e.params[1])}execute(e){let t=e.getAllPlayers().filter(e=>e.country&&!e.defeated);if(-1!==this.houseId&&(t=t.filter(e=>e.country?.id===this.houseId)),t.length)for(var i of t[0].getOwnedObjectsByType(ObjectType.Infantry))i.unitOrderTrait.isIdle()&&i.unitOrderTrait.addTask(new CheerTask)}}const crateConfigs=new Map([[0,e=>{e=e.rules.powerups.powerups.find(e=>e.type===PowerupType.Money);return e?{...e,data:"5000"}:void 0}],[1,PowerupType.Unit],[2,PowerupType.HealBase],[3,PowerupType.Cloak],[4,PowerupType.Explosion],[5,PowerupType.Napalm],[6,PowerupType.Money],[7,PowerupType.Darkness],[8,PowerupType.Reveal],[9,PowerupType.Armor],[10,PowerupType.Speed],[11,PowerupType.Firepower],[12,PowerupType.ICBM],[13,void 0],[14,PowerupType.Veteran],[15,void 0],[16,PowerupType.Gas],[17,PowerupType.Tiberium],[18,void 0]]);class CreateCrateExecutor extends TriggerExecutor{execute(e){var t=Number(this.action.params[1]),i=this.action.params[6],r=e.map.getTileAtWaypoint(i);if(r)if(crateConfigs.has(t)){const s=crateConfigs.get(t);t="function"==typeof s?s(e):e.rules.powerups.powerups.find(e=>e.type===s);t&&e.crateGeneratorTrait.spawnCrateAt(r,t,e)}else e.crateGeneratorTrait.spawnRandomCrateAt(r,e);else console.warn(`No valid location found for waypoint ${i}. `+`Skipping action ${this.getDebugName()}.`)}}class CreateRadarEventExecutor extends TriggerExecutor{execute(e){var t=Number(this.action.params[1])-1;if(Object.values(RadarEventType).includes(t)){var i=this.action.params[6],r=e.map.getTileAtWaypoint(i);if(r)for(var s of e.getCombatants())e.traits.get(RadarTrait_RadarTrait).addEventForPlayer(t,s,r,e);else console.warn(`No valid location found for waypoint ${i}. `+`Skipping action ${this.getDebugName()}.`)}else console.warn(`Unknown radar event type "${1+t}". Skipping action ${this.getDebugName()}.`)}}class DestroyObjectExecutor extends TriggerExecutor{execute(e,t){for(var i of t)i instanceof GameObject&&i.isSpawned&&e.destroyObject(i)}}class DestroyTagExecutor extends TriggerExecutor{execute(e){var t=this.action.params[1];e.triggers.destroyTag(t)}}class DestroyTriggerExecutor extends TriggerExecutor{execute(e){var t=this.action.params[1];e.triggers.destroyTrigger(t)}}class DetonateWarheadExecutor extends TriggerExecutor{execute(r){var s=Number(this.action.params[1]),e=this.action.params[6],a=r.map.getTileAtWaypoint(e);if(a){let t;try{t=r.rules.getWeaponByInternalId(s)}catch(e){if(e instanceof RangeError)return void console.warn(`Weapon with internal ID "${s}" not found. `+`Skipping action ${this.getDebugName()}.`);throw e}let e;try{e=r.rules.getWarhead(t.warhead)}catch(e){return void console.warn(`Warhead "${t.warhead}" not found. `+`Skipping action ${this.getDebugName()}.`)}let i=new Warhead(e);var n=r.map.tileOccupation.getBridgeOnTile(a),o=n?.tileElevation??0,s=r.map.getTileZone(a);i.detonate(r,t.damage,a,o,Coords.tile3dToWorld(a.rx+.5,a.ry+.5,a.z+o),s,n?CollisionType.OnBridge:CollisionType.None,r.createTarget(n,a),void 0)}else console.warn(`No valid location found for waypoint ${e}. `+`Skipping action ${this.getDebugName()}.`)}}class EvictOccupiersExecutor extends TriggerExecutor{execute(e,t){for(var i of t)i instanceof GameObject&&i.isBuilding()&&i.garrisonTrait&&!i.isDestroyed&&i.garrisonTrait.evacuate(e)}}class FireSaleExecutor extends TriggerExecutor{constructor(e,t){super(e,t),this.houseId=Number(e.params[1])}execute(e){var t=e.getAllPlayers().find(e=>e.country?.id===this.houseId);if(t)for(var i of t.buildings)e.sellTrait.sell(i)}}class ForceEndExecutor extends TriggerExecutor{execute(e){e.end()}}class ForceTriggerExecutor extends TriggerExecutor{execute(e){var t=this.action.params[1];e.triggers.forceTrigger(t,e)}}class GlobalVariableExecutor extends TriggerExecutor{constructor(e,t,i){super(e,t),this.value=i,this.variableIdx=Number(e.params[1])}execute(e){e.triggers.toggleGlobalVariable(this.variableIdx,this.value)}}class IronCurtainExecutor extends TriggerExecutor{execute(e){var t,i,r=this.action.params[6],s=e.map.getTileAtWaypoint(r);s?!(t=e.getAllPlayers().find(e=>!e.defeated&&e.country?.name===this.trigger.houseName))||(i=[...e.rules.superWeaponRules.values()].find(e=>e.type===SuperWeaponType.IronCurtain))&&e.traits.get(SuperWeaponsTrait).activateEffect(i,t,e,s,void 0,!0):console.warn(`No valid location found for waypoint ${r}. `+`Skipping action ${this.getDebugName()}.`)}}class LightningStrikeExecutor extends TriggerExecutor{execute(e){var t,i,r=this.action.params[6],s=e.map.getTileAtWaypoint(r);s?!(t=e.getAllPlayers().find(e=>!e.defeated&&e.country?.name===this.trigger.houseName))||(i=[...e.rules.superWeaponRules.values()].find(e=>e.type===SuperWeaponType.LightningStorm))&&e.traits.get(SuperWeaponsTrait).activateEffect(i,t,e,s,void 0,!0):console.warn(`No valid location found for waypoint ${r}. `+`Skipping action ${this.getDebugName()}.`)}}class LocalVariableExecutor extends TriggerExecutor{constructor(e,t,i){super(e,t),this.value=i,this.variableIdx=Number(e.params[1])}execute(e){e.triggers.toggleLocalVariable(this.variableIdx,this.value)}}class NoActionExecutor extends TriggerExecutor{execute(){}}class NukeStrikeExecutor extends TriggerExecutor{execute(e){var t,i,r=this.action.params[6],s=e.map.getTileAtWaypoint(r);s?!(t=e.getAllPlayers().find(e=>!e.defeated&&e.country?.name===this.trigger.houseName))||(i=[...e.rules.superWeaponRules.values()].find(e=>e.type===SuperWeaponType.MultiMissile))&&e.traits.get(SuperWeaponsTrait).activateEffect(i,t,e,s,void 0,!0):console.warn(`No valid location found for waypoint ${r}. `+`Skipping action ${this.getDebugName()}.`)}}class TriggerAnimEvent{constructor(e,t){this.name=e,this.tile=t,this.type=EventType.TriggerAnim}}class PlayAnimAtExecutor extends TriggerExecutor{execute(e){var t,i=this.action,r=Number(i.params[1]),s=e.rules.getAnimationName(r);void 0!==s?(t=i.params[6],(i=e.map.getTileAtWaypoint(t))?e.events.dispatch(new TriggerAnimEvent(s,i)):console.warn(`No valid location found for waypoint ${t}. `+`Skipping action ${this.getDebugName()}.`)):console.warn(`No animation found for index "${r}". Skipping action `+this.getDebugName())}}class TriggerSoundFxEvent{constructor(e,t){this.soundId=e,this.tile=t,this.type=EventType.TriggerSoundFx}}class PlaySoundFxAtExecutor extends TriggerExecutor{execute(e){var t=this.action,i=t.params[1],r=t.params[6],t=e.map.getTileAtWaypoint(r);t?e.events.dispatch(new TriggerSoundFxEvent(i,t)):console.warn(`No valid location found for waypoint ${r}. `+`Skipping action ${this.getDebugName()}.`)}}class PlaySoundFxExecutor extends TriggerExecutor{execute(e){e.events.dispatch(new TriggerSoundFxEvent(this.action.params[1]))}}class TriggerEvaEvent{constructor(e){this.soundId=e,this.type=EventType.TriggerEva}}class PlaySpeechExecutor extends TriggerExecutor{execute(e){e.events.dispatch(new TriggerEvaEvent(this.action.params[1]))}}class ReshroudMapExecutor extends TriggerExecutor{execute(e){for(var t of e.getCombatants())e.mapShroudTrait.resetShroud(t,e)}}class ResizePlayerViewExecutor extends TriggerExecutor{execute(e){var[t,i,r,s]=this.action.params.slice(2,6).map(Number);e.map.mapBounds.updateRawLocalSize({x:t,y:i,width:r,height:s})}}class RevealAroundWaypointExecutor extends TriggerExecutor{execute(e){var t=Number(this.action.params[1]),i=e.map.getTileAtWaypoint(t);if(i)for(var r of e.getCombatants())e.mapShroudTrait.getPlayerShroud(r)?.revealAround(i,e.rules.general.revealTriggerRadius);else console.warn(`No valid location found for waypoint ${t}. `+`Skipping action ${this.getDebugName()}.`)}}class RevealMapExecutor extends TriggerExecutor{execute(e){for(var t of e.getCombatants())e.mapShroudTrait.revealMap(t,e)}}class SellBuildingExecutor extends TriggerExecutor{execute(e,t){for(var i of t)i instanceof GameObject&&i.isBuilding()&&!i.isDestroyed&&e.sellTrait.sell(i)}}class SetAmbientLightExecutor extends TriggerExecutor{execute(e){var t=Number(this.action.params[1])/100;e.mapLightingTrait.setTargetAmbientIntensity(t)}}function int32ToFloat32(e){let t=new DataView(new ArrayBuffer(4));return t.setInt32(0,e),t.getFloat32(0)}class SetAmbientRateExecutor extends TriggerExecutor{execute(e){var t=int32ToFloat32(Number(this.action.params[1]));e.mapLightingTrait.setAmbientChangeRate(t)}}class SetAmbientStepExecutor extends TriggerExecutor{execute(e){var t=int32ToFloat32(Number(this.action.params[1]));e.mapLightingTrait.setAmbientChangeStep(t)}}class TriggerStopSoundFxEvent{constructor(e){this.tile=e,this.type=EventType.TriggerStopSoundFx}}class StopSoundFxAtExecutor extends TriggerExecutor{execute(e){var t=this.action.params[6],i=e.map.getTileAtWaypoint(t);i?e.events.dispatch(new TriggerStopSoundFxEvent(i)):console.warn(`No valid location found for waypoint ${t}. `+`Skipping action ${this.getDebugName()}.`)}}class TriggerTextEvent{constructor(e){this.label=e,this.type=EventType.TriggerText}}class TextTriggerExecutor extends TriggerExecutor{execute(e){e.events.dispatch(new TriggerTextEvent(this.action.params[1]))}}class TimerExtendExecutor extends TriggerExecutor{execute(e){e.countdownTimer.addSeconds(Number(this.action.params[1]))}}class TimerSetExecutor extends TriggerExecutor{execute(e){e.countdownTimer.setSeconds(Number(this.action.params[1]))}}class TimerShortenExecutor extends TriggerExecutor{execute(e){e.countdownTimer.addSeconds(-Number(this.action.params[1]))}}class TimerStartExecutor extends TriggerExecutor{execute(e){e.countdownTimer.start()}}class TimerStopExecutor extends TriggerExecutor{execute(e){e.countdownTimer.stop()}}class TimerTextExecutor extends TriggerExecutor{execute(e){e.countdownTimer.text=this.action.params[1]}}class ToggleTriggerExecutor extends TriggerExecutor{constructor(e,t,i){super(e,t),this.triggerEnable=i}execute(e){var t=this.action.params[1];e.triggers.setTriggerEnabled(t,this.triggerEnable)}}class TurnOnOffBuildingExecutor extends TriggerExecutor{constructor(e,t,i){super(e,t),this.turnOn=i}execute(e,t){for(var i of t)i instanceof GameObject&&i.isBuilding()&&i.poweredTrait?.setTurnedOn(this.turnOn)}}class UnrevealAroundWaypointExecutor extends TriggerExecutor{execute(e){var t=Number(this.action.params[1]),i=e.map.getTileAtWaypoint(t);if(i)for(var r of e.getCombatants())e.mapShroudTrait.getPlayerShroud(r)?.unrevealAround(i,e.rules.general.revealTriggerRadius);else console.warn(`No valid location found for waypoint ${t}. `+`Skipping action ${this.getDebugName()}.`)}}class TriggerExecutorFactory{create(e,t){switch(e.type){case TriggerActionType.NoAction:return new NoActionExecutor(e,t);case TriggerActionType.FireSale:return new FireSaleExecutor(e,t);case TriggerActionType.TextTrigger:return new TextTriggerExecutor(e,t);case TriggerActionType.DestroyTrigger:return new DestroyTriggerExecutor(e,t);case TriggerActionType.ChangeHouse:return new ChangeHouseExecutor(e,t);case TriggerActionType.RevealMap:return new RevealMapExecutor(e,t);case TriggerActionType.RevealAroundWaypoint:return new RevealAroundWaypointExecutor(e,t);case TriggerActionType.PlaySoundFx:return new PlaySoundFxExecutor(e,t);case TriggerActionType.PlaySpeech:return new PlaySpeechExecutor(e,t);case TriggerActionType.ForceTrigger:return new ForceTriggerExecutor(e,t);case TriggerActionType.TimerStart:return new TimerStartExecutor(e,t);case TriggerActionType.TimerStop:return new TimerStopExecutor(e,t);case TriggerActionType.TimerExtend:return new TimerExtendExecutor(e,t);case TriggerActionType.TimerShorten:return new TimerShortenExecutor(e,t);case TriggerActionType.TimerSet:return new TimerSetExecutor(e,t);case TriggerActionType.GlobalSet:return new GlobalVariableExecutor(e,t,!0);case TriggerActionType.GlobalClear:return new GlobalVariableExecutor(e,t,!1);case TriggerActionType.DestroyObject:return new DestroyObjectExecutor(e,t);case TriggerActionType.AddOneTimeSuperWeapon:return new AddSuperWeaponExecutor(e,t,!0);case TriggerActionType.AddRepeatingSuperWeapon:return new AddSuperWeaponExecutor(e,t,!1);case TriggerActionType.AllChangeHouse:return new ChangeHouseAllExecutor(e,t);case TriggerActionType.ResizePlayerView:return new ResizePlayerViewExecutor(e,t);case TriggerActionType.PlayAnimAt:return new PlayAnimAtExecutor(e,t);case TriggerActionType.DetonateWarhead:return new DetonateWarheadExecutor(e,t);case TriggerActionType.ReshroudMap:return new ReshroudMapExecutor(e,t);case TriggerActionType.EnableTrigger:return new ToggleTriggerExecutor(e,t,!0);case TriggerActionType.DisableTrigger:return new ToggleTriggerExecutor(e,t,!1);case TriggerActionType.CreateRadarEvent:return new CreateRadarEventExecutor(e,t);case TriggerActionType.LocalSet:return new LocalVariableExecutor(e,t,!0);case TriggerActionType.LocalClear:return new LocalVariableExecutor(e,t,!1);case TriggerActionType.SellBuilding:return new SellBuildingExecutor(e,t);case TriggerActionType.TurnOffBuilding:return new TurnOnOffBuildingExecutor(e,t,!1);case TriggerActionType.TurnOnBuilding:return new TurnOnOffBuildingExecutor(e,t,!0);case TriggerActionType.ApplyOneHundredDamage:return new ApplyDamageExecutor(e,t,100);case TriggerActionType.ForceEnd:return new ForceEndExecutor(e,t);case TriggerActionType.DestroyTag:return new DestroyTagExecutor(e,t);case TriggerActionType.SetAmbientStep:return new SetAmbientStepExecutor(e,t);case TriggerActionType.SetAmbientRate:return new SetAmbientRateExecutor(e,t);case TriggerActionType.SetAmbientLight:return new SetAmbientLightExecutor(e,t);case TriggerActionType.NukeStrike:return new NukeStrikeExecutor(e,t);case TriggerActionType.PlaySoundFxAt:return new PlaySoundFxAtExecutor(e,t);case TriggerActionType.UnrevealAroundWaypoint:return new UnrevealAroundWaypointExecutor(e,t);case TriggerActionType.LightningStrike:return new LightningStrikeExecutor(e,t);case TriggerActionType.TimerText:return new TimerTextExecutor(e,t);case TriggerActionType.CreateCrate:return new CreateCrateExecutor(e,t);case TriggerActionType.IronCurtainAt:return new IronCurtainExecutor(e,t);case TriggerActionType.EvictOccupiers:return new EvictOccupiersExecutor(e,t);case TriggerActionType.Cheer:return new CheerExecutor(e,t);case TriggerActionType.StopSoundsAt:return new StopSoundFxAtExecutor(e,t);default:throw new Error(`Unhandled action type "${TriggerActionType[e.type]}"`)}}}class TriggerCondition{constructor(e,t){this.event=e,this.trigger=t,this.blocking=!1,this.targets=[]}init(e){e=e.getAllPlayers().find(e=>e.country?.name===this.trigger.houseName);e&&(this.player=e)}setTargets(e){this.targets=e}reset(){}getDebugName(){return`${this.event.triggerId}[${this.event.eventIndex}] (${this.trigger.name}).`}}class AmbientLightCondition extends TriggerCondition{constructor(e,t,i){super(e,t),this.type=i,this.threshold=Number(e.params[1])/100}check(e){var t=this.previousAmbient,e=e.mapLightingTrait.getAmbient().ambient;return this.previousAmbient=e,void 0!==t&&t!==e&&("above"===this.type?e>=this.threshold&&t<this.threshold:e<=this.threshold&&t>this.threshold)}}class AnyEventCondition extends TriggerCondition{check(e){return!0}}class AttackedByAnyCondition extends TriggerCondition{check(r,e){return e.filter(e=>{if(e.type!==EventType.ObjectAttacked)return!1;let t=e.target;if(!t.isTechno()||!this.targets.includes(t))return!1;var i=e.attacker?.player;return(!i||!r.alliances.areAllied(i,t.owner)&&i!==t.owner)&&!e.incidental}).map(e=>e.target)}}class AttackedByHouseCondition extends TriggerCondition{constructor(e,t){super(e,t),this.houseId=Number(e.params[1])}check(e,t){return t.filter(e=>{if(e.type!==EventType.ObjectAttacked)return!1;let t=e.target;if(!t.isTechno()||!this.targets.includes(t))return!1;e=e.attacker?.player;return e&&(-1===this.houseId||e?.country?.id===this.houseId)}).map(e=>e.target)}}class BuildingExistsCondition extends TriggerCondition{constructor(e,t,i=!1){super(e,t),this.negate=i,this.objectIndex=Number(e.params[1])}check(){if(!this.player)return!1;for(var e of this.player.buildings)if(e.rules.index===this.objectIndex)return!this.negate;return this.negate}}class BuildObjectTypeCondition extends TriggerCondition{constructor(e,t,i){super(e,t),this.objectType=i,this.objectIndex=Number(e.params[1])}check(e,t){return t.some(e=>e.type===EventType.ObjectSpawn&&e.gameObject.type===this.objectType&&e.gameObject.rules.index===this.objectIndex)}}class ComesNearWaypointCondition extends TriggerCondition{constructor(e,t){super(e,t)}init(e){super.init(e);var t=Number(this.event.params[1]);this.waypointTile=e.map.getTileAtWaypoint(t),this.waypointTile||console.warn(`No valid location found for waypoint ${t}. `+`Skipping event ${this.getDebugName()}.`)}check(t,e){if(!this.waypointTile||!this.player)return!1;for(var i of e)if(i.type===EventType.EnterTile&&i.source.owner===this.player){let e=new RangeHelper(t.map.tileOccupation);if(e.tileDistance(i.target,this.waypointTile)<2)return!0}return!1}}class CreditsBelowCondition extends TriggerCondition{constructor(e,t){super(e,t),this.threshold=Number(e.params[1])}check(e,t){return!!this.player&&this.player.credits<this.threshold}}class CreditsExceedCondition extends TriggerCondition{constructor(e,t){super(e,t),this.threshold=Number(e.params[1])}check(e,t){return!!this.player&&this.player.credits>this.threshold}}class CrossHorizLineCondition extends TriggerCondition{constructor(e,t){super(e,t),this.houseId=Number(this.event.params[1])}check(e,t){return t.filter(t=>t.type===EventType.EnterTile&&t.source.zone!==ZoneType.Air&&this.targets.some(e=>e.ry===t.target.ry)&&(-1===this.houseId||t.source.owner.country?.id===this.houseId)).map(e=>e.target)}}class CrossVertLineCondition extends TriggerCondition{constructor(e,t){super(e,t),this.houseId=Number(this.event.params[1])}check(e,t){return t.filter(t=>t.type===EventType.EnterTile&&t.source.zone!==ZoneType.Air&&this.targets.some(e=>e.rx===t.target.rx)&&(-1===this.houseId||t.source.owner.country?.id===this.houseId)).map(e=>e.target)}}class DestroyedAllBuildingsCondition extends TriggerCondition{constructor(e,t){super(e,t),this.allDestroyed=!1,this.houseId=Number(e.params[1])}check(e,t){return!!this.allDestroyed||!!t.some(e=>{if(e.type!==EventType.ObjectDestroy)return!1;let t=e.target;return!(!t.isBuilding()||t.owner.country?.id!==this.houseId)&&!t.owner.buildings.size})&&(this.allDestroyed=!0)}}class DestroyedAllCondition extends TriggerCondition{constructor(e,t){super(e,t),this.allDestroyed=!1,this.houseId=Number(e.params[1])}check(e,t){return!!this.allDestroyed||!!t.some(e=>{if(e.type!==EventType.ObjectDestroy)return!1;let t=e.target;return!(!t.isTechno()||t.owner.country?.id!==this.houseId)&&!t.owner.getOwnedObjects(!0).length})&&(this.allDestroyed=!0)}}class DestroyedAllUnitsCondition extends TriggerCondition{constructor(e,t){super(e,t),this.allDestroyed=!1,this.houseId=Number(e.params[1])}check(e,t){return!!this.allDestroyed||!!t.some(e=>{if(e.type!==EventType.ObjectDestroy)return!1;let t=e.target;return!(!t.isUnit()||t.owner.country?.id!==this.houseId)&&!this.hasUnitsLeft(t.owner)})&&(this.allDestroyed=!0)}hasUnitsLeft(e){var t;for(t of[ObjectType.Aircraft,ObjectType.Vehicle,ObjectType.Infantry])if(e.getOwnedObjectsByType(t,!0).length)return!0;return!1}}class DestroyedAllUnitsLandCondition extends TriggerCondition{constructor(e,t){super(e,t),this.allDestroyed=!1,this.houseId=Number(e.params[1])}check(e,t){return!!this.allDestroyed||!!t.some(e=>{if(e.type!==EventType.ObjectDestroy)return!1;let t=e.target;return!(!t.isUnit()||t.owner.country?.id!==this.houseId)&&!this.hasLandUnitsLeft(t.owner)})&&(this.allDestroyed=!0)}hasLandUnitsLeft(e){var t;for(t of[ObjectType.Vehicle,ObjectType.Infantry])if(e.getOwnedObjectsByType(t,!0).filter(e=>!e.rules.naval).length)return!0;return!1}}class DestroyedAllUnitsNavalCondition extends TriggerCondition{constructor(e,t){super(e,t),this.allDestroyed=!1,this.houseId=Number(e.params[1])}check(e,t){return!!this.allDestroyed||!!t.some(e=>{if(e.type!==EventType.ObjectDestroy)return!1;let t=e.target;return!(!t.isVehicle()||t.owner.country?.id!==this.houseId)&&!t.owner.getOwnedObjectsByType(ObjectType.Vehicle,!0).filter(e=>e.rules.naval).length})&&(this.allDestroyed=!0)}}class DestroyedBridgeCondition extends TriggerCondition{check(r,e){return e.filter(e=>{if(e.type!==EventType.ObjectDestroy)return!1;let t=e.target;if(!t.isOverlay()||!t.isBridge())return!1;e=t.bridgeTrait?.bridgeSpec;if(!e)return!1;let i=r.map.bridges.findAllBridgeTiles(e);return i.find(e=>this.targets.includes(e))}).map(e=>e.target.tile)}}class DestroyedBuildingsCondition extends TriggerCondition{constructor(e,t){super(e,t),this.count=0,this.threshold=Number(e.params[1])}check(e,t){if(!this.player)return!1;if(this.count>=this.threshold)return!0;for(var i of t)if(i.type===EventType.ObjectDestroy){let e=i.target;e.isBuilding()&&e.owner.country?.id===this.houseId&&this.count++}return this.count>=this.threshold}}class DestroyedByAnyCondition extends TriggerCondition{check(r,e){return e.filter(e=>{if(e.type!==EventType.ObjectDestroy)return!1;let t=e.target;if(!t.isTechno()||!this.targets.includes(t))return!1;var i=e.attackerInfo?.player;return(!i||!r.alliances.areAllied(i,t.owner)&&i!==t.owner)&&!e.incidental}).map(e=>e.target)}}class DestroyedOrCapturedCondition extends TriggerCondition{check(e,t){return t.filter(e=>{if(e.type!==EventType.ObjectDestroy&&e.type!==EventType.ObjectOwnerChange)return!1;let t=e.target;return!(!t.isTechno()||!this.targets.includes(t))}).map(e=>e.target)}}class DestroyedOrCapturedOrInfiltratedCondition extends TriggerCondition{constructor(){super(...arguments),this.eventsFilter=[EventType.ObjectDestroy,EventType.ObjectOwnerChange,EventType.BuildingInfiltration]}check(e,t){return t.filter(e=>{if(!this.eventsFilter.includes(e.type))return!1;let t=e.target;return!(!t.isTechno()||!this.targets.includes(t))}).map(e=>e.target)}}class DestroyedUnitsCondition extends TriggerCondition{constructor(e,t){super(e,t),this.count=0,this.threshold=Number(e.params[1])}check(e,t){if(!this.player)return!1;if(this.count>=this.threshold)return!0;for(var i of t)if(i.type===EventType.ObjectDestroy){let e=i.target;e.isUnit()&&e.owner.country?.id===this.houseId&&this.count++}return this.count>=this.threshold}}class ElapsedScenarioTimeCondition extends TriggerCondition{constructor(e,t){super(e,t),this.timerTicks=Number(this.event.params[1])*GameSpeed.BASE_TICKS_PER_SECOND}check(e){return e.currentTick>this.timerTicks}}class ElapsedTimeCondition extends TriggerCondition{constructor(e,t){super(e,t),this.elapsedTicks=0,this.timerTicks=Number(this.event.params[1])*GameSpeed.BASE_TICKS_PER_SECOND}check(e){return this.elapsedTicks++>this.timerTicks}reset(){this.elapsedTicks=0}}class EnteredByCondition extends TriggerCondition{constructor(e,t){super(e,t),this.houseId=Number(this.event.params[1])}check(e,t){return t.filter(e=>(e.type===EventType.EnterObject||e.type===EventType.EnterTile)&&this.targets.includes(e.target)&&(e.type!==EventType.EnterTile||e.source.zone!==ZoneType.Air)&&(-1===this.houseId||e.source.owner.country?.id===this.houseId)).map(e=>e.target)}}class GlobalVariableCondition extends TriggerCondition{constructor(e,t,i){super(e,t),this.value=i,this.blocking=!0,this.variableIdx=Number(e.params[1])}check(e){return e.triggers.getGlobalVariable(this.variableIdx)===this.value}}class HealthBelowAnyCondition extends TriggerCondition{constructor(e,t,i){super(e,t),this.threshold=i}check(e,t){return t.filter(e=>{if(e.type!==EventType.HealthChange)return!1;let t=e.target;return!(!t.isTechno()||!this.targets.includes(t))&&(e.currentHealth<this.threshold&&e.prevHealth>this.threshold)}).map(e=>e.target)}}class HealthBelowCombatCondition extends TriggerCondition{constructor(e,t,i){super(e,t),this.threshold=i}check(e,t){return t.filter(e=>{if(e.type!==EventType.InflictDamage)return!1;let t=e.target;return!(!t.isTechno()||!this.targets.includes(t))&&(e.currentHealth<this.threshold&&e.prevHealth>this.threshold)}).map(e=>e.target)}}class LocalVariableCondition extends TriggerCondition{constructor(e,t,i){super(e,t),this.value=i,this.blocking=!0,this.variableIdx=Number(e.params[1])}check(e){return e.triggers.getLocalVariable(this.variableIdx)===this.value}}class LowPowerCondition extends TriggerCondition{constructor(e,t){super(e,t),this.houseId=Number(this.event.params[1])}init(e){super.init(e),this.targetPlayer=e.getAllPlayers().find(e=>e.country?.id===this.houseId)}check(){return!!this.targetPlayer?.powerTrait?.isLowPower()}}class NoEventCondition extends TriggerCondition{check(e){return!1}}class NoFactoriesLeftCondition extends TriggerCondition{check(){if(!this.player)return!1;for(var e of this.player.buildings)if(e.factoryTrait)return!1;return!0}}class PickupCrateAnyCondition extends TriggerCondition{check(e,t){return t.some(e=>e.type===EventType.CratePickup)}}class PickupCrateCondition extends TriggerCondition{check(e,t){return t.filter(e=>e.type===EventType.CratePickup&&this.targets.includes(e.source)).map(e=>e.source)}}class RandomDelayCondition extends TriggerCondition{constructor(){super(...arguments),this.elapsedTicks=0}check(e){return this.timerTicks??(this.timerTicks=Math.floor(e.generateRandomInt(50,150)/100*Number(this.event.params[1]))*GameSpeed.BASE_TICKS_PER_SECOND),this.elapsedTicks++>this.timerTicks}reset(){this.timerTicks=void 0,this.elapsedTicks=0}}class SpiedByCondition extends TriggerCondition{constructor(e,t){super(e,t),this.houseId=Number(this.event.params[1])}check(e,t){return t.filter(e=>e.type===EventType.BuildingInfiltration&&this.targets.includes(e.target)&&(-1===this.houseId||e.source.owner.country?.id===this.houseId)).map(e=>e.target)}}class SpyEnteringAsHouseCondition extends TriggerCondition{constructor(e,t){super(e,t),this.houseId=Number(e.params[1])}check(e,t){return t.filter(e=>{if(e.type!==EventType.BuildingInfiltration)return!1;var t=e.target;return!!this.targets.includes(t)&&(-1===this.houseId||e.source.disguiseTrait?.getDisguise()?.owner?.country?.id===this.houseId)}).map(e=>e.target)}}class SpyEnteringAsInfantryCondition extends TriggerCondition{constructor(e,t){super(e,t),this.infantryIdx=Number(e.params[1])}check(e,t){return t.filter(e=>{if(e.type!==EventType.BuildingInfiltration)return!1;var t=e.target;return!!this.targets.includes(t)&&e.source.disguiseTrait?.getDisguise()?.rules.index===this.infantryIdx}).map(e=>e.target)}}class TimerExpiredCondition extends TriggerCondition{check(e,t){return t.some(e=>e.type===EventType.TimerExpire)}}class TriggerConditionFactory{create(e,t){switch(e.type){case TriggerEventType.NoEvent:return new NoEventCondition(e,t);case TriggerEventType.EnteredBy:return new EnteredByCondition(e,t);case TriggerEventType.SpiedBy:return new SpiedByCondition(e,t);case TriggerEventType.AttackedByAny:return new AttackedByAnyCondition(e,t);case TriggerEventType.DestroyedByAny:return new DestroyedByAnyCondition(e,t);case TriggerEventType.AnyEvent:return new AnyEventCondition(e,t);case TriggerEventType.DestroyedAllUnits:return new DestroyedAllUnitsCondition(e,t);case TriggerEventType.DestroyedAllBuildings:return new DestroyedAllBuildingsCondition(e,t);case TriggerEventType.DestroyedAll:return new DestroyedAllCondition(e,t);case TriggerEventType.CreditsExceed:return new CreditsExceedCondition(e,t);case TriggerEventType.ElapsedTime:return new ElapsedTimeCondition(e,t);case TriggerEventType.MissionTimerExpired:return new TimerExpiredCondition(e,t);case TriggerEventType.DestroyedBuildings:return new DestroyedBuildingsCondition(e,t);case TriggerEventType.DestroyedUnits:return new DestroyedUnitsCondition(e,t);case TriggerEventType.NoFactoriesLeft:return new NoFactoriesLeftCondition(e,t);case TriggerEventType.BuildBuilding:return new BuildObjectTypeCondition(e,t,ObjectType.Building);case TriggerEventType.BuildUnit:return new BuildObjectTypeCondition(e,t,ObjectType.Vehicle);case TriggerEventType.BuildInfantry:return new BuildObjectTypeCondition(e,t,ObjectType.Infantry);case TriggerEventType.BuildAircraft:return new BuildObjectTypeCondition(e,t,ObjectType.Aircraft);case TriggerEventType.CrossesHorizontalLine:return new CrossHorizLineCondition(e,t);case TriggerEventType.CrossesVerticalLine:return new CrossVertLineCondition(e,t);case TriggerEventType.GlobalIsSet:return new GlobalVariableCondition(e,t,!0);case TriggerEventType.GlobalIsCleared:return new GlobalVariableCondition(e,t,!1);case TriggerEventType.DestroyedOrCaptured:return new DestroyedOrCapturedCondition(e,t);case TriggerEventType.LowPower:return new LowPowerCondition(e,t);case TriggerEventType.DestroyedBridge:return new DestroyedBridgeCondition(e,t);case TriggerEventType.BuildingExists:return new BuildingExistsCondition(e,t);case TriggerEventType.ComesNearWaypoint:return new ComesNearWaypointCondition(e,t);case TriggerEventType.LocalIsSet:return new LocalVariableCondition(e,t,!0);case TriggerEventType.LocalIsCleared:return new LocalVariableCondition(e,t,!1);case TriggerEventType.FirstDamagedCombat:return new HealthBelowCombatCondition(e,t,100);case TriggerEventType.HalfHealthCombat:return new HealthBelowCombatCondition(e,t,50);case TriggerEventType.QuarterHealthCombat:return new HealthBelowCombatCondition(e,t,25);case TriggerEventType.FirstDamagedAny:return new HealthBelowAnyCondition(e,t,100);case TriggerEventType.HalfHealthAny:return new HealthBelowAnyCondition(e,t,50);case TriggerEventType.QuarterHealthAny:return new HealthBelowAnyCondition(e,t,25);case TriggerEventType.AttackedByHouse:return new AttackedByHouseCondition(e,t);case TriggerEventType.AmbientLightBelow:return new AmbientLightCondition(e,t,"below");case TriggerEventType.AmbientLightAbove:return new AmbientLightCondition(e,t,"above");case TriggerEventType.ElapsedScenarioTime:return new ElapsedScenarioTimeCondition(e,t);case TriggerEventType.DestroyedOrCapturedOrInfiltrated:return new DestroyedOrCapturedOrInfiltratedCondition(e,t);case TriggerEventType.PickupCrate:return new PickupCrateCondition(e,t);case TriggerEventType.PickupCrateAny:return new PickupCrateAnyCondition(e,t);case TriggerEventType.RandomDelay:return new RandomDelayCondition(e,t);case TriggerEventType.CreditsBelow:return new CreditsBelowCondition(e,t);case TriggerEventType.SpyEnteringAsHouse:return new SpyEnteringAsHouseCondition(e,t);case TriggerEventType.SpyEnteringAsInfantry:return new SpyEnteringAsInfantryCondition(e,t);case TriggerEventType.DestroyedAllUnitsNaval:return new DestroyedAllUnitsNavalCondition(e,t);case TriggerEventType.DestroyedAllUnitsLand:return new DestroyedAllUnitsLandCondition(e,t);case TriggerEventType.BuildingNotExists:return new BuildingExistsCondition(e,t,!0);default:throw new Error(`Unhandled trigger event type "${TriggerEventType[e.type]}"`)}}}class TriggerManager{constructor(){this.disposables=new CompositeDisposable,this.triggerInstances=new Map,this.targetsByTag=new Map,this.conditionFactory=new TriggerConditionFactory,this.executorFactory=new TriggerExecutorFactory,this.pendingGameEvents=[],this.globalVariables=new Map,this.localVariables=new Map}init(i){var t,e,r,s,a=i.map.getInitialMapObjects()["technos"];for(let t of a)if(t.tag){let e=this.targetsByTag.get(t.tag);e||(e=[],this.targetsByTag.set(t.tag,e));var n=i.map.tiles.getByMapCoords(t.rx,t.ry);!n||(n=i.map.getObjectsOnTile(n).find(e=>e.name===t.name&&e.type===t.type))&&e.push(n)}for(t of i.map.getCellTags()){var o=i.map.tiles.getByMapCoords(t.coords.x,t.coords.y);if(o){let e=this.targetsByTag.get(t.tagId);e||(e=[],this.targetsByTag.set(t.tagId,e)),e.push(o)}else console.warn(`CellTag out of bounds at (${t.coords.x}, ${t.coords.y}). Skipping.`)}for([e,r]of i.map.getVariables())this.localVariables.set(e,r.clone());for(s of i.map.getTriggers())this.triggerInstances.set(s.id,this.createTriggerInstance(s,i));this.disposables.add(i.events.subscribe(e=>this.pendingGameEvents.push(e)))}createTriggerInstance(i,r){let s=this.targetsByTag.get(i.tag.id)??[];return{trigger:i,conditions:i.events.map(e=>{let t=this.conditionFactory.create(e,i);return t.setTargets(s),t.init(r),t}).sort((e,t)=>Number(t.blocking)-Number(e.blocking)),targets:s,remainingTargets:new Set(i.tag.repeatType===TagRepeatType.OnceAll?s:[]),disabled:i.disabled,finished:!1}}update(i){var r,s=this.pendingGameEvents.splice(0,this.pendingGameEvents.length);for(r of this.triggerInstances.values())if(!r.finished&&!r.disabled){let e=!0,t=[];for(var a of r.conditions){var n=a.check(i,s);if("boolean"==typeof n?n||(e=!1):n.length?t.push(...n):e=!1,a.blocking&&!e)break}if(e){var o=r.trigger;r.conditions.forEach(e=>e.reset?.());let e=[];if(o.tag.repeatType===TagRepeatType.OnceAll){for(var l of t)r.remainingTargets.delete(l);if(r.remainingTargets.size)continue;e=t.length?[t[t.length-1]]:[]}else e=r.targets;this.executeActions(o,e,i),o.tag.repeatType!==TagRepeatType.Repeat&&(r.finished=!0)}}}executeActions(t,i,r){for(var s of t.actions){let e=this.executorFactory.create(s,t);e.execute(r,i)}}setTriggerEnabled(e,t){let i=this.triggerInstances.get(e);i&&(i.disabled=!t)}forceTrigger(e,t){e=this.triggerInstances.get(e);e&&this.executeActions(e.trigger,e.targets,t)}destroyTrigger(e){this.triggerInstances.delete(e)}destroyTag(e){let t=[];for(var[i,r]of this.triggerInstances)r.trigger.tag.id===e&&t.push(i);for(var s of t)this.destroyTrigger(s)}getGlobalVariable(e){return!!this.globalVariables.get(e)?.value}toggleGlobalVariable(e,t){let i=this.globalVariables.get(e);void 0===i?this.globalVariables.set(e,new Variable("No name",t)):i.value=t}getLocalVariable(e){return!!this.localVariables.get(e)?.value}toggleLocalVariable(e,t){let i=this.localVariables.get(e);void 0===i?this.localVariables.set(e,new Variable("No name",t)):i.value=t}dispose(){this.disposables.dispose()}}class TimerExpireEvent{constructor(e){this.target=e,this.type=EventType.TimerExpire}}class CountdownTimer{constructor(){this.ticks=0,this.running=!1}getSeconds(){return Math.floor(this.ticks/GameSpeed.BASE_TICKS_PER_SECOND)}setSeconds(e){this.ticks=Math.max(0,Math.floor(GameSpeed.BASE_TICKS_PER_SECOND*e))}addSeconds(e){this.ticks=Math.max(0,this.ticks+Math.floor(GameSpeed.BASE_TICKS_PER_SECOND*e))}start(){this.running=!0}stop(){this.running=!1}isRunning(){return this.running}update(e){this.running&&(0<this.ticks?this.ticks--:(this.running=!1,e.events.dispatch(new TimerExpireEvent(this))))}}(NotifyObjectTraitAdd=NotifyObjectTraitAdd||{}).onAdd=Symbol(),function(e){e[e.NotStarted=0]="NotStarted",e[e.Started=1]="Started",e[e.Ended=2]="Ended"}(GameStatus=GameStatus||{});class Game{get onEnd(){return this._onEnd.asEvent()}constructor(e,t,i,r,s,a,n,o,l,h,c,d,u,p,g){this.updatableObjects=new Set,this.constructionWorkers=new Map,this.currentTick=0,this.currentTime=0,this.countdownTimer=new CountdownTimer,this._onEnd=new EventDispatcher,this.afterTickCallbacks=[],this.events=new GameEventBus,this.traits=new Traits,this.debugText=new BoxedVar(""),this.world=e,this.map=t,this.rules=i,this.art=r,this.ai=s,this.id=a,this.startTimestamp=n,this.prng=Prng.factory(a,n),this.gameOpts=o,this.gameModeType=l,this.playerList=h,this.unitSelection=c,this.alliances=d,this.desiredSpeed=new BoxedVar(GameSpeed.computeGameSpeed(o.gameSpeed)),this.speed=new BoxedVar(this.desiredSpeed.value),this.nextObjectId=u,this.objectFactory=p,this.botManager=g,this.triggers=new TriggerManager}addPlayer(e){this.playerList.addPlayer(e),this.constructionWorkers.set(e,this.createConstructionWorker(e))}getPlayer(e){return this.playerList.getPlayerAt(e)}getPlayerByName(e){return this.playerList.getPlayerByName(e)}getAiPlayerName(e){let t;return t="number"==typeof e?e:this.gameOpts.aiPlayers.indexOf(e),`@@AI${t+1}@@`}getPlayerNumber(e){return this.playerList.getPlayerNumber(e)}getCombatants(){return this.playerList.getCombatants()}getCivilianPlayer(){return this.playerList.getCivilian()}getAllPlayers(){return this.playerList.getAll()}getNonNeutralPlayers(){return this.playerList.getNonNeutral()}areFriendly(e,t){return e.owner===t.owner||this.alliances.areAllied(e.owner,t.owner)}getWorld(){return this.world}createConstructionWorker(e){return new ConstructionWorker(e,this.rules,this.art,this.map,this)}getConstructionWorker(e){var t=this.constructionWorkers.get(e);if(!t)throw new Error(`No construction worker found for player "${e.name}"`);return t}getUnitSelection(){return this.unitSelection}init(e){this.localPlayer=e,this.createMapObjects(),this.createPlayerInitialUnits(),this.map.terrain.computeAllPassabilityGraphs(),this.mapShroudTrait.init(this),this.crateGeneratorTrait.init(this),this.playerList.getAll().forEach(e=>e.credits=this.gameOpts.credits),this.rules.mpDialogSettings.alliesAllowed&&this.createInitialTeams(),this.botManager.init(this),this.triggers.init(this)}start(){this.status=GameStatus.Started,this.currentTick=0,this.currentTime=0,this.botManager.onGameStart()}createInitialTeams(){for(let t=0;t<this.gameOpts.maxSlots;t++){var i=[...this.gameOpts.humanPlayers,...this.gameOpts.aiPlayers].filter(e=>e?.teamId===t&&e.countryId!==OBS_COUNTRY_ID).map(e=>isHumanPlayerInfo(e)?e.name:this.getAiPlayerName(e));if(1<i.length)for(let t=0;t<i.length-1;t++)for(let e=t+1;e<i.length;e++){var r=this.getPlayerByName(i[t]),s=this.getPlayerByName(i[e]),s=this.alliances.setAlliance(r,s,AllianceStatus.Formed);this.onAllianceChange(s,r,!0)}}}createMapObjects(){var e=this.rules.general.harvesterUnit.every(e=>!isBetween(this.rules.getObject(e,ObjectType.Vehicle).techLevel,0,this.rules.mpDialogSettings.techLevel)),t=this.map.getInitialMapObjects();this.createInitialMapTerrains(t.terrains,e),this.createInitialMapOverlays(t.overlays,e),this.createInitialMapSmudges(t.smudges),this.createInitialMapTechnos(t.technos)}createInitialMapTerrains(e,t){for(var i of e){var r,s,a=i.name;this.validateMapObjectRulesAndArt(a,ObjectType.Terrain)&&((r=this.map.tiles.getByMapCoords(i.rx,i.ry))?(s=this.rules.getObject(a,ObjectType.Terrain),t&&s.spawnsTiberium||(a=this.createObject(ObjectType.Terrain,a),this.spawnObject(a,r))):console.warn(`Invalid map object location (${i.rx},${i.ry})`,i))}}createInitialMapOverlays(e,r){let s=new Map,a=new Map;var n,t,i,o=this.map.bridges.findMapHighBridgeHeadTiles();let l=this.map.bridges.findBridgeSpecsForHeadTiles([...o]);for(n of e){var h=this.rules.getOverlayName(n.id);if(this.validateMapObjectRulesAndArt(h,ObjectType.Overlay)){let e=this.createObject(ObjectType.Overlay,h);e.overlayId=n.id,e.value=n.value;let t=n.rx,i=n.ry;if(e.isBridge()&&e.isHighBridge()){e.position.tileElevation=4;var c=l.find(e=>rectContainsPoint({x:e.start.rx,y:e.start.ry,...this.map.bridges.getBridgeSize(e)},{x:t,y:i}));if(c){var{type:h,isXBridge:d,isHigh:c}=c;if(!c){console.warn(`Expected high bridge but found low bridge overlay at location (${t},${i})`),e.dispose();continue}d!==e.isXBridge()&&(u=BridgeOverlayTypes.calculateHighBridgeOverlayId(h,d),e.overlayId!==u&&(e.overlayId=u,e.name=this.rules.getOverlayName(u)))}t+=e.isXBridge()?0:-1,i+=e.isXBridge()?-1:0}var u,d=this.map.tiles.getByMapCoords(t,i);if(d)if(e.rules.tiberium&&(void 0===(u=OreOverlayTypes.getOverlayTibType(n.id))||void 0!==(u=OreSpread.calculateOverlayId(u,d))&&u!==n.id&&(e.dispose(),e=this.createObject(ObjectType.Overlay,this.rules.getOverlayName(u)),e.overlayId=u,e.value=n.value)),BridgeOverlayTypes.isLowBridge(n.id))BridgeOverlayTypes.isBridgePlaceholder(n.id)||(s.set(d,n.value),1===n.value?a.set(d,e):e.dispose());else{if(e.isTiberium())if(this.map.getObjectsOnTile(d).find(e=>e.isTerrain())){e.dispose();continue}r&&e.isTiberium()?e.dispose():this.spawnObject(e,d)}else console.warn(`Invalid map object location (${t},${i})`,n),e.dispose()}}for([t,i]of a){var p=i.isXBridge(),g=this.map.tiles.getByMapCoords(t.rx+(p?0:-1),t.ry+(p?-1:0)),p=this.map.tiles.getByMapCoords(t.rx+(p?0:1),t.ry+(p?1:0));g&&p&&(0===s.get(g)||2===s.get(p))?(i.value=0,this.spawnObject(i,g)):(i.dispose(),console.warn(`Invalid bridge segment @${t.rx},${t.ry}. Skipping.`))}var m,e=[...a.keys()].filter(e=>this.map.bridges.getPieceAtTile(e)?.headType!==BridgeHeadType.None);let y=[...this.map.bridges.findBridgeSpecsForHeadTiles([...e]),...l];for(m of y)for(var T of this.map.bridges.findBridgePieces(m))T.obj.bridgeTrait.bridgeSpec=m;var f,e=y.map(e=>this.map.bridges.findAllBridgeTiles(e)).flat(),v=BridgeOverlayTypes.bridgePlaceholderIds[0],b=this.rules.getOverlayName(v);for(f of e){let e=this.createObject(ObjectType.Overlay,b);e.overlayId=v,this.spawnObject(e,f)}}createInitialMapSmudges(e){for(var t of e){var i=t.name,r=this.map.tiles.getByMapCoords(t.rx,t.ry);r?(i=this.createObject(ObjectType.Smudge,i),this.spawnObject(i,r)):console.warn(`Invalid map object location (${t.rx},${t.ry})`,t)}}createInitialMapTechnos(e){let t=new Map(this.playerList.getAll().filter(e=>!!e.country).map(e=>[e.country.name,e])),r=this.map.getTags();for(let i of e){var s=i.name;if(this.validateMapObjectRulesAndArt(s,i.type)){var a=this.map.tiles.getByMapCoords(i.rx,i.ry);if(a){var n=t.get(i.owner);if(n){if(n.isNeutral){let t=this.createObject(i.type,s);i.tag&&(t.tag=r.find(e=>e.id===i.tag)),t.healthTrait.health=i.health/256*100;let e=!1;if(!t.healthTrait.health){if(!t.isBuilding()||!t.rules.leaveRubble){t.dispose();continue}e=!0}if(i.isInfantry()||i.isVehicle()||i.isAircraft()){t.direction=(-i.direction/256*360+360)%360,i.isInfantry()&&(t.position.subCell=i.subCell);let e=!1;i.onBridge&&(void 0===a.onBridgeLandType?console.warn(`Cannot place unit "${i.name}" on a bridge because `+`no bridge was found at ${a.rx}, `+a.ry):e=!0),t.onBridge=e,t.zone=getZoneType(e?a.onBridgeLandType:a.landType),e&&(t.position.tileElevation+=this.map.tileOccupation.getBridgeOnTile(a)?.tileElevation??0),i.veterancy&&t.veteranTrait?.setRelativeXP(i.veterancy)}else t.poweredTrait?.setTurnedOn(i.poweredOn);this.changeObjectOwner(t,n),this.spawnObject(t,a),e&&this.destroyObject(t,void 0,!0)}}else console.warn(`Invalid owner "${i.owner}" for map object`,i)}else console.warn(`Invalid map object location (${i.rx},${i.ry})`,i)}}}validateMapObjectRulesAndArt(e,t){return this.rules.hasObject(e,t)?!!this.art.hasObject(e,t)||(console.warn(`Map object '${e}' has no art section. Skipping.`),!1):(console.warn(`Map object '${e}' has no rules section. Skipping.`),!1)}createPlayerInitialUnits(){let e=this.playerList.getCombatants().map(e=>e.country);var i=[...this.rules.infantryRules.values(),...this.rules.vehicleRules.values()].filter(t=>t.allowedToStartInMultiplayer&&!t.naval&&-1!==t.techLevel&&t.techLevel<=this.rules.mpDialogSettings.techLevel&&!this.rules.general.baseUnit.includes(t.name)&&e.some(e=>t.isAvailableTo(e)&&t.hasOwner(e)));for(let l of this.playerList.getCombatants()){var h=this.map.startingLocations[l.startLocation],c=this.map.tiles.getByMapCoords(h.x,h.y);if(!c)throw new Error(`Invalid player starting position (${h.x},${h.y})`);let t=this.rules.general.baseUnit.find(e=>{let t=this.rules.getObject(e,ObjectType.Vehicle);return t.isAvailableTo(l.country)&&t.hasOwner(l.country)});if(!t)throw new Error("No suitable MCV found for player country "+l.country?.name);h=this.rules.getObject(t,ObjectType.Vehicle),h=this.createUnitForPlayer(h,l);this.spawnObject(h,c);let e=StartingUnitsGenerator.generate(this.gameOpts.unitCount,[...this.rules.vehicleRules.keys()],i,l.country);this.gameModeType===GameModeType.Unholy&&e.push(...this.rules.general.baseUnit.filter(e=>e!==t).map(e=>({name:e,type:ObjectType.Vehicle,count:1})));var d,u,p;let r=[],s=!1,a=new CardinalTileFinder(this.map.tiles,this.map.mapBounds,c,4,4,e=>!this.map.getGroundObjectsOnTile(e).find(e=>!(e.isSmudge()||e.isOverlay()&&e.isTiberium()))&&0<this.map.terrain.getPassableSpeed(e,SpeedType.Foot,!1,!1)),n=new Map,o=0;for({name:d,type:u,count:p}of e){let i=p;for(;0<i;){let t;if(s||(t=a.getNextTile(),t?r.push(t):s=!0),s&&r.length){var g=r[o];let e=n.get(g);e||(e=new CardinalTileFinder(this.map.tiles,this.map.mapBounds,g,1,0,e=>!this.map.getGroundObjectsOnTile(e).find(e=>!(e.isSmudge()||e.isOverlay()&&e.isTiberium()))&&0<this.map.terrain.getPassableSpeed(e,SpeedType.Foot,!1,!1)),n.set(g,e)),o=(o+1)%r.length,t=e.getNextTile()}if(t){var m,y=this.rules.getObject(d,u);if(u===ObjectType.Vehicle){g=this.createUnitForPlayer(y,l);this.applyInitialVeteran(g,l),this.spawnObject(g,t),i--}else{if(u!==ObjectType.Infantry)throw new Error("Should not reach this line");for(m of Infantry_Infantry.SUB_CELLS.slice(0,i)){let e=this.createUnitForPlayer(y,l);e.position.subCell=m,this.applyInitialVeteran(e,l),this.spawnObject(e,t),i--}}}else i--}}}}applyInitialVeteran(e,t){e.veteranTrait&&(this.rules.general.veteran.initialVeteran?e.veteranTrait.setVeteranLevel(VeteranLevel.Elite):t.country.hasVeteranUnit(e.type,e.name)&&e.veteranTrait.setVeteranLevel(VeteranLevel.Veteran))}createObject(e,t){return this.objectFactory.create(e,t,this.rules,this.art)}createUnitForPlayer(e,t){if(![ObjectType.Aircraft,ObjectType.Vehicle,ObjectType.Infantry].includes(e.type))throw new Error(`Attempted to create an invalid unit type "${e.type}"`);let i=this.createObject(e.type,e.name);return this.changeObjectOwner(i,t),i.purchaseValue=this.sellTrait.computePurchaseValue(i.rules,t),i}createProjectile(e,t,i,r,s){let a=this.createObject(ObjectType.Projectile,e);return a.fromWeapon=i,a.fromObject=t,a.fromPlayer=t.owner,a.target=r,a.isShrapnel=s,a}createLooseProjectile(e,t,i){var r=this.rules.getWeapon(e),s=r.projectile,a=this.rules.getProjectile(s),e=this.rules.getWarhead(r.warhead),e={minRange:0,projectileRules:a,range:Number.POSITIVE_INFINITY,rules:r,speed:Weapon.computeSpeed(r,a),type:WeaponType.Primary,warhead:new Warhead(e)};let n=this.createObject(ObjectType.Projectile,s);return n.fromWeapon=e,n.fromObject=void 0,n.fromPlayer=t,n.target=i,n}createSuperWeapon(e,t,i=!1){var r=this.rules.getSuperWeapon(e);return new SuperWeapon(e,r,t,i)}createTarget(e,t){return new Target(e,t,this.map.tileOccupation)}isValidTarget(e){if(e){if(!e.isSpawned||e.isCrashing)return!1;if(!(e.rules.legalTarget||e.isBuilding()&&e.rules.hospital))return!1;if(e.isBuilding()&&e.rules.invisibleInGame)return!1}return!0}spawnObject(e,t){if(e.isTechno()&&e.limboData)throw new Error(`Object ${e.name}#${e.id} is in limbo. Use unlimboObject instead or clear limboData first`);this.doSpawnObject(e,t)}unspawnObject(e){e.isTechno()&&e.owner&&e.owner.removeOwnedObject(e),this.doUnspawnObject(e)}limboObject(e,t){e.limboData=t,this.doUnspawnObject(e)}unlimboObject(e,t,i=!1){var r=e.limboData;if(!r)throw new Error(`Object ${e.name}#${e.id} has no limboData attached`);e.limboData=void 0,this.doSpawnObject(e,t);let s=this.getUnitSelection();r.selected&&!i&&s.addToSelection(e),void 0!==r.controlGroup&&s.addUnitsToGroup(r.controlGroup,[e],!1)}doSpawnObject(t,e){var i,r;t.position.tile=e,t.isBuilding()&&(r=t.art.foundationCenter,i=e.rx+r.x,r=e.ry+r.y,t.centerTile=this.map.tiles.getByMapCoords(i,r)??this.map.tiles.getPlaceholderTile(i,r)),this.world.spawnObject(t),(t.cachedTraits.tick.length||t.isProjectile()||t.isDebris()||t.isTechno())&&this.updatableObjects.add(t),t.isTechno()&&this.map.technosByTile.add(t),t.isProjectile()||t.isDebris()||this.map.tileOccupation.occupyTileRange(e,t),t.art.canHideThings&&this.map.tileOcclusion.addOccluder(t),t.onSpawn(this),this.traits.filter(NotifySpawn_NotifySpawn).forEach(e=>{e[NotifySpawn_NotifySpawn.onSpawn](t,this)}),this.events.dispatch(new ObjectSpawnEvent(t))}doUnspawnObject(t){var e=t.tile;t.isProjectile()||t.isDebris()||this.map.tileOccupation.unoccupyTileRange(e,t),t.art.canHideThings&&this.map.tileOcclusion.removeOccluder(t),t.isTechno()&&(this.unitSelection.cleanupUnit(t),this.map.technosByTile.remove(t)),this.world.removeObject(t),this.updatableObjects.delete(t),t.onUnspawn(this),this.traits.filter(NotifyUnspawn_NotifyUnspawn).forEach(e=>{e[NotifyUnspawn_NotifyUnspawn.onUnspawn](t,this)}),this.events.dispatch(new ObjectUnspawnEvent(t))}destroyObject(t,i,e=!1,r=!1){if(t.isDestroyed)throw new Error(`Object with ID "${t.id}" is already destroyed`);if(t.isTechno()){let e=t.mindControllableTrait?.getOriginalOwner()??t.owner;!i||t.isBuilding()&&!e.isCombatant()||(i.player.addUnitsKilled(t.type,1),i.player===e||this.alliances.areAllied(i.player,e)||(i.player.score+=t.rules.points)),e.isNeutral||e.addUnitsLost(t.type,1)}if(t.isDestroyed=!0,t.healthTrait&&(t.healthTrait.health=0),t.onDestroy(this,i,e),this.traits.filter(NotifyDestroy_NotifyDestroy).forEach(e=>{e[NotifyDestroy_NotifyDestroy.onDestroy](t,this,i)}),i?.obj?.traits.filter(NotifyTargetDestroy).forEach(e=>{e[NotifyTargetDestroy.onDestroy](i.obj,t,i.weapon,this)}),this.events.dispatch(new ObjectDestroyEvent(t,i,r)),t.isBuilding()&&t.rules.leaveRubble&&t.deathType!==DeathType.Temporal){t.owner.removeOwnedObject(t),this.unitSelection.cleanupUnit(t);r=this.map.tileOccupation.calculateTilesForGameObject(t.tile,t);this.map.terrain.invalidateTiles(r),t.art.canHideThings&&this.map.tileOcclusion.removeOccluder(t),this.updatableObjects.delete(t),t.onUnspawn(this),this.traits.filter(NotifyUnspawn_NotifyUnspawn).forEach(e=>{e[NotifyUnspawn_NotifyUnspawn.onUnspawn](t,this)}),this.events.dispatch(new ObjectUnspawnEvent(t))}else if(t.isSpawned)this.unspawnObject(t);else if(t.isTechno()&&t.owner){if(!t.limboData)throw new Error(`Object with ID "${t.id}" should be in limbo but has no limboData`);t.owner.removeOwnedObject(t)}t.dispose()}getObjectById(e){return this.world.getObjectById(e)}changeObjectOwner(t,e){const i=t.owner;i&&i.removeOwnedObject(t),e.addOwnedObject(t),i&&i!==e&&(this.traits.filter(NotifyOwnerChange_NotifyOwnerChange).forEach(e=>{e[NotifyOwnerChange_NotifyOwnerChange.onChange](t,i,this)}),t.onOwnerChange(i,this),this.events.dispatch(new ObjectOwnerChangeEvent(t,i)),i===this.localPlayer&&t.owner!==this.localPlayer&&(this.unitSelection.removeFromSelection([t]),this.unitSelection.removeUnitsFromGroup([t])))}addObjectTrait(t,i){t.addTrait(i),this.traits.filter(NotifyObjectTraitAdd).forEach(e=>{e[NotifyObjectTraitAdd.onAdd](t,i,this)})}onAllianceChange(t,e,i){this.events.dispatch(new AllianceChangeEvent(t,i?AllianceEventType.Formed:AllianceEventType.Broken,e)),this.traits.filter(NotifyAllianceChange).forEach(e=>{e[NotifyAllianceChange.onChange](t,i,this)})}update(){if(this.status!==GameStatus.NotStarted){this.botManager.update(this),this.status!==GameStatus.Ended&&(void 0===this.lastGameEndCheck||1e3<=this.currentTime-this.lastGameEndCheck)&&(this.checkGameEndConditions(),this.lastGameEndCheck=this.currentTime);for(var e of[...this.updatableObjects])e.isSpawned&&e.update(this);if(this.playerList.getCombatants().forEach(e=>e.cheerCooldownTicks=Math.max(0,e.cheerCooldownTicks-1)),this.traits.filter(NotifyTick).forEach(e=>{e[NotifyTick.onTick](this)}),this.localPlayer&&!this.localPlayer.isObserver&&!this.localPlayer.defeated){var t=this.unitSelection.getSelectedUnits();if(1===t.length){let i=t[0];if(i.isTechno()&&i.owner!==this.localPlayer){let t=this.mapShroudTrait.getPlayerShroud(this.localPlayer);this.map.tileOccupation.calculateTilesForGameObject(i.tile,i).find(e=>!t.isShrouded(e,i.tileElevation))||(this.unitSelection.deselectAll(),this.unitSelection.cleanupUnit(i))}}}for(var i of this.afterTickCallbacks)i();this.afterTickCallbacks.length=0,this.triggers.update(this),this.countdownTimer.update(this),this.currentTick++,this.currentTime+=1e3/GameSpeed.BASE_TICKS_PER_SECOND}}afterTick(e){this.afterTickCallbacks.push(e)}checkGameEndConditions(){this.updateDefeatedPlayers(this.playerList.getCombatants()),(this.localPlayer?.defeated&&!this.localPlayer.isObserver||!this.alliances.getHostilePlayers().length&&1<this.gameOpts.humanPlayers.length+this.gameOpts.aiPlayers.filter(e=>!!e).length)&&this.end()}end(){this.status!==GameStatus.Ended&&(this.status=GameStatus.Ended,this._onEnd.dispatch(this,void 0))}updateDefeatedPlayers(e){let r=this.stalemateDetectTrait?.isStale()&&0===this.stalemateDetectTrait.getCountdownTicks(),s=this.gameOpts.shortGame;e.forEach(t=>{let i;if(r)i=!0;else{let e;e=s?(e=[...t.getOwnedObjectsByType(ObjectType.Building,!0)].some(e=>!e.rules.insignificant),e||t.getOwnedObjects(!0).some(e=>this.rules.general.baseUnit.includes(e.name))):t.getOwnedObjects(!0).some(e=>!e.rules.insignificant&&!e.limboData?.inTransport),i=!e}var e;i&&(t.defeated=!0,(e=this.alliances.getHostilePlayers().some(e=>!e.first.isAi||!e.second.isAi))&&(t.isObserver=!0),this.removeAllPlayerAssets(t),this.events.dispatch(new PlayerDefeatedEvent(t)),e&&(this.mapShroudTrait.getPlayerShroud(t)?.revealAll(),e=t.radarTrait.isDisabled(),t.radarTrait.setDisabled(!1),e&&this.events.dispatch(new RadarOnOffEvent(t,!0))))})}removeAllPlayerAssets(e){e.getOwnedObjects().forEach(e=>{e.isDestroyed||(e.isBuilding()&&e.rules.returnable&&e.rules.needsEngineer&&!e.garrisonTrait?this.changeObjectOwner(e,this.getCivilianPlayer()):e.isBuilding()&&e.wallTrait||this.destroyObject(e,void 0,!0))}),e.getOwnedObjects(!0).forEach(e=>{e.isDestroyed||(e.limboData?.inTransport||e.isBuilding()&&e.wallTrait?this.changeObjectOwner(e,this.getCivilianPlayer()):this.destroyObject(e,void 0,!0))})}isAssetRedistributionEnabled(){return this.rules.mpDialogSettings.mustAlly&&!this.rules.mpDialogSettings.allyChangeAllowed}redistributeAllPlayerAssets(e){if(e.isObserver)return!1;if(!this.isAssetRedistributionEnabled())return!1;let t=this.alliances.getAllies(e).filter(e=>!e.isAi&&!e.defeated);if(0<t.length){var i,r=[...t].sort((e,t)=>t.score-e.score)[0];for(i of e.getOwnedObjects(!0))this.changeObjectOwner(i,r);var s,a=Math.floor(e.credits/t.length),e=e.credits%t.length;for(s of t)s.credits+=a;return t[0].credits+=e,!0}return!1}generateRandomInt(e,t){return this.prng.generateRandomInt(e,t)}generateRandom(){return this.prng.generateRandom()}getHash(){return fnv32a([...new Uint8Array(new Float64Array([this.prng.getLastRandom()??0]).buffer),this.nextObjectId.value,...this.world.getAllObjects().map(e=>e.getHash()),...this.playerList.getAll().map(e=>e.getHash()),this.alliances.getHash(),...this.traits.getAll().map(e=>e.getHash?.()??0)])}debugGetState(){return{currentTick:this.currentTick,lastRandom:this.prng.getLastRandom(),nextObjectId:this.nextObjectId.value,objects:this.world.getAllObjects().map(e=>e.debugGetState()),players:this.playerList.getAll().map(e=>e.debugGetState()),alliances:this.alliances.debugGetState(),traits:this.traits.getAll().reduce((e,t)=>{var i=t.debugGetState?.();return void 0!==i&&(e[t.constructor.name]=i),e},{})}}dispose(){this.world.getAllObjects().forEach(e=>e.dispose()),this.playerList.getAll().forEach(e=>e.dispose()),this.constructionWorkers.forEach(e=>e.dispose()),this.botManager.dispose(),this.triggers.dispose(),this.map.dispose(),this.traits.dispose()}}const RAD_LEVEL_CAP=1e3,PERCENT_AT_MAX=0;class MapRadiationTrait{get onChange(){return this._onChange.asEvent()}constructor(e){this.map=e,this.radSites=new Map,this.radLevelByTile=new Map,this._onChange=new EventDispatcher}getRadLevel(e){return this.radLevelByTile.get(e)}[NotifyTick.onTick](e){var t;this.radLevelByTile.size&&(t=e.rules.radiation,void 0===this.nextDamage?this.nextDamage=Math.max(0,t.radApplicationDelay-1):this.nextDamage<=0?(this.applyDamage(e),this.nextDamage=Math.max(0,t.radApplicationDelay)):this.nextDamage--,void 0===this.nextDecay?this.nextDecay=Math.max(0,t.radLevelDelay-1):this.nextDecay<=0?(this.applyDecay(Math.ceil(t.radLevelDelay/t.radDurationMultiple)),this.radLevelByTile.size?this.nextDecay=Math.max(0,t.radLevelDelay):this.nextDecay=void 0):this.nextDecay--)}applyDamage(a){let n=a.rules.radiation,o=new Warhead(a.rules.getWarhead(n.radSiteWarhead));this.radLevelByTile.forEach((e,t)=>{var i,r,s=Math.min(n.radLevelMax,e)*n.radLevelFactor;for(i of a.map.getGroundObjectsOnTile(t).filter(e=>e.isUnit()&&!(e.isInfantry()&&e.stance===StanceType.Paradrop&&1<e.tileElevation)))o.canDamage(i,t,i.zone)&&(0<(r=o.computeDamage(s,i,a))&&o.inflictDamage(r,i,void 0,a,!0))})}applyDecay(r){var e=new Set(this.radLevelByTile.keys());this.radLevelByTile.clear(),this.radSites.forEach(({radLevel:e,radius:t},i)=>{e-=r;e<=0?this.radSites.delete(i):(this.radSites.set(i,{radLevel:e,radius:t}),this.setRadLevelAround(i,t,e))}),this._onChange.dispatch(this,e)}createRadSite(e,t,i){(t-=this.radSites.get(e)?.radLevel??0)<=0||(this.radSites.set(e,{radLevel:(this.radSites.get(e)?.radLevel??0)+t,radius:i}),(t=this.setRadLevelAround(e,i,t)).size&&this._onChange.dispatch(this,t))}setRadLevelAround(e,t,i){let r=new RangeHelper(this.map.tileOccupation),s=new RadialTileFinder(this.map.tiles,this.map.mapBounds,e,{width:1,height:1},0,t,e=>!!e,!1);var a;let n=new Set;for(;a=s.getNextTile();){var o=r.tileDistance(e,a);o<=t&&(o=Math.ceil(lerp(i,i*PERCENT_AT_MAX,o/t)),this.radLevelByTile.set(a,Math.min(RAD_LEVEL_CAP,(this.radLevelByTile.get(a)??0)+o)),n.add(a))}return n}getRadSiteLevel(e){return this.radSites.get(e)?.radLevel}}class ActionFactory{constructor(){this.factories=new Map}registerFactory(e,t){this.factories.set(e,t)}create(e){let t=this.factories.get(e);if(!t)throw new Error("No factory registered for action type "+e);return t.create()}}class UnitSelectionLite{constructor(e){this.player=e,this.selectedUnits=new Set}update(e){var t,i=[...e].reverse().find(e=>e.owner!==this.player);i&&(e=[i]),this.selectedUnits.clear();for(t of e)t.rules.selectable&&this.selectedUnits.add(t)}getSelectedUnits(){return[...this.selectedUnits].map(e=>e.isDisposed&&e.replacedBy?e.replacedBy:e).filter(e=>!e.isDestroyed&&!e.isCrashing)}isSelected(e){return this.selectedUnits.has(e)}}class OrderActionContext{constructor(){this.unitSelectionByPlayer=new Map}getOrCreateSelection(e){let t=this.unitSelectionByPlayer.get(e);return t||(t=new UnitSelectionLite(e),this.unitSelectionByPlayer.set(e,t)),t}}!function(e){e[e.NoAction=0]="NoAction",e[e.DropPlayer=1]="DropPlayer",e[e.ObserveGame=2]="ObserveGame",e[e.ResignGame=3]="ResignGame",e[e.DebugCommand=4]="DebugCommand",e[e.PlaceBuilding=5]="PlaceBuilding",e[e.SellObject=6]="SellObject",e[e.ToggleRepair=7]="ToggleRepair",e[e.SelectUnits=8]="SelectUnits",e[e.OrderUnits=9]="OrderUnits",e[e.UpdateQueue=10]="UpdateQueue",e[e.ToggleAlliance=11]="ToggleAlliance",e[e.ActivateSuperWeapon=12]="ActivateSuperWeapon",e[e.PingLocation=13]="PingLocation"}(ActionType=ActionType||{});class Action{constructor(e){this.actionType=e}unserialize(e){}serialize(){return new Uint8Array}print(){return""}}class NoAction extends Action{constructor(){super(ActionType.NoAction)}process(){}}class NoActionFactory{create(){return new NoAction}}class BuildingPlaceEvent{constructor(e){this.target=e,this.type=EventType.BuildingPlace}}class BuildingFailedPlaceEvent{constructor(e,t,i){this.name=e,this.player=t,this.tile=i,this.type=EventType.BuildingFailedPlace}}(NotifyPlaceBuilding=NotifyPlaceBuilding||{}).onPlace=Symbol();class PlaceBuildingAction extends Action{constructor(e){super(ActionType.PlaceBuilding),this.game=e}unserialize(e){let t=new DataStream(e);this.buildingRules=this.game.rules.getTechnoByInternalId(t.readUint32(),ObjectType.Building),this.tile={x:t.readUint16(),y:t.readUint16()}}serialize(){let e=new DataStream(8);return e.writeUint32(this.buildingRules.index),e.writeUint16(this.tile.x),e.writeUint16(this.tile.y),e.toUint8Array()}print(){return`Place building ${this.buildingRules.name} at tile (${this.tile.x}, ${this.tile.y})`}process(){var e=this.game.map.tiles.getByMapCoords(this.tile.x,this.tile.y);if(e){var t=this.player;const i=this.tryPlaceBuilding(t,e);i?(this.game.traits.filter(NotifyPlaceBuilding).forEach(e=>{e[NotifyPlaceBuilding.onPlace](i,this.game)}),this.game.events.dispatch(new BuildingPlaceEvent(i))):this.game.events.dispatch(new BuildingFailedPlaceEvent(this.buildingRules.name,t,e))}else console.warn(`Tile ${this.tile.x},${this.tile.y} doesn't exist`)}tryPlaceBuilding(r,s){var a=this.buildingRules;if(r.production){let i=r.production.getQueueForObject(a);if(i.status===QueueStatus.Ready&&i.getFirst().rules===a){let t=this.game.getConstructionWorker(r);if(r.production.isAvailableForProduction(a)&&t.canPlaceAt(a.name,s,{normalizedTile:!0})){s=t.placeAt(a.name,s,!0);r.addUnitsBuilt(a,1),i.shift(a,1);let e=r.production.getPrimaryFactory(FactoryType.BuildingType);return e&&(e.factoryTrait.status=FactoryStatus.Delivering),s[0]}}}}}class PlaceBuildingActionFactory{constructor(e){this.game=e}create(){return new PlaceBuildingAction(this.game)}}class SellObjectAction extends Action{constructor(e){super(ActionType.SellObject),this.game=e}unserialize(e){this.objectId=new DataStream(e).readUint32()}serialize(){return new DataStream(4).writeUint32(this.objectId).toUint8Array()}print(){return"Sell object "+this.objectId}process(){var t=this.player;if(this.game.getWorld().hasObjectId(this.objectId)){let e=this.game.getObjectById(this.objectId);e.isTechno()&&t===e.owner&&e.isSpawned&&(e.isBuilding()?e.buildStatus===BuildStatus.Ready&&!e.warpedOutTrait.isActive():e.traits.find(DockableTrait)?.dock?.rules.unitSell)&&this.game.sellTrait.sell(e)}}}class SellObjectActionFactory{constructor(e){this.game=e}create(){return new SellObjectAction(this.game)}}const orderPriorities=[OrderType.Occupy,OrderType.Dock,OrderType.Attack,OrderType.Capture,OrderType.Repair,OrderType.EnterTransport,OrderType.PlaceBomb,OrderType.Deploy,OrderType.Gather];!function(e){e[e.Default=0]="Default",e[e.Mini=1]="Mini",e[e.Scroll=2]="Scroll",e[e.NoScroll=10]="NoScroll",e[e.Select=18]="Select",e[e.Move=31]="Move",e[e.NoMove=41]="NoMove",e[e.MoveMini=42]="MoveMini",e[e.NoActionMini=52]="NoActionMini",e[e.AttackRange=53]="AttackRange",e[e.AttackNoRange=58]="AttackNoRange",e[e.AttackMini=63]="AttackMini",e[e.Guard=68]="Guard",e[e.GuardMini=73]="GuardMini",e[e.Unknown1=78]="Unknown1",e[e.Unknown2=88]="Unknown2",e[e.Occupy=89]="Occupy",e[e.NoOccupy=99]="NoOccupy",e[e.OccupyMini=100]="OccupyMini",e[e.Deploy=110]="Deploy",e[e.NoDeploy=119]="NoDeploy",e[e.Unknown3=120]="Unknown3",e[e.Sell=129]="Sell",e[e.SellMini=139]="SellMini",e[e.NoSell=149]="NoSell",e[e.RepairMove=150]="RepairMove",e[e.SideRepair=170]="SideRepair",e[e.NoRepair=190]="NoRepair",e[e.Unknown4=191]="Unknown4",e[e.Unknown5=199]="Unknown5",e[e.Dynamite=204]="Dynamite",e[e.Unknown6=209]="Unknown6",e[e.Unknown7=214]="Unknown7",e[e.Unknown8=219]="Unknown8",e[e.Unknown9=224]="Unknown9",e[e.Unknown10=229]="Unknown10",e[e.Unknown11=234]="Unknown11",e[e.Unknwon12=239]="Unknwon12",e[e.Unknown13=249]="Unknown13",e[e.Para=259]="Para",e[e.Unknown14=269]="Unknown14",e[e.Storm=279]="Storm",e[e.EngineerDamage=299]="EngineerDamage",e[e.C4=309]="C4",e[e.Nuke=319]="Nuke",e[e.Unknown16=329]="Unknown16",e[e.Power=339]="Power",e[e.Unknown17=345]="Unknown17",e[e.Iron=346]="Iron",e[e.Unknown18=351]="Unknown18",e[e.Unknown19=356]="Unknown19",e[e.Chrono=357]="Chrono",e[e.DefuseBomb=369]="DefuseBomb",e[e.NoAction=384]="NoAction",e[e.Pan=385]="Pan",e[e.Unknown21=394]="Unknown21",e[e.AttackMove=404]="AttackMove",e[e.Unknown23=413]="Unknown23",e[e.Unknown24=422]="Unknown24",e[e.Unknown25=431]="Unknown25",e[e.Unknown26=432]="Unknown26",e[e.Unknown27=433]="Unknown27",e[e.Unknown28=434]="Unknown28",e[e.Beacon=435]="Beacon",e[e.ForceField=450]="ForceField",e[e.NoForceField=460]="NoForceField",e[e.Mutate=470]="Mutate",e[e.AirStrike=480]="AirStrike",e[e.Dominate=488]="Dominate",e[e.PsychicReveal=496]="PsychicReveal",e[e.SpyPlane=504]="SpyPlane",e[e.SpyPlaneMini=512]="SpyPlaneMini",e[e.NukeMini=513]="NukeMini",e[e.StormMini=514]="StormMini",e[e.PsychicRevealMini=515]="PsychicRevealMini",e[e.DominateMini=516]="DominateMini"}(PointerType=PointerType||{}),function(e){e[e.None=0]="None",e[e.Move=1]="Move",e[e.Attack=2]="Attack",e[e.Enter=3]="Enter",e[e.Capture=4]="Capture",e[e.SpecialAttack=5]="SpecialAttack"}(OrderFeedbackType=OrderFeedbackType||{});class Order{constructor(e){this.orderType=e,this.targetOptional=!0,this.minimapAllowed=!0,this.singleSelectionRequired=!1,this.terminal=!1,this.feedbackType=OrderFeedbackType.None}getPointerType(e,t){return e?PointerType.Mini:PointerType.Default}set(e,t){return this.sourceObject=e,this.target=t,this}isValid(){return!0}isAllowed(){return!0}onAdd(e,t){return!0}}class ObjectMorphEvent{constructor(e,t){this.from=e,this.to=t,this.type=EventType.ObjectMorph}}class MorphIntoTask extends Task{constructor(e){super(),this.game=e}onStart(e){if(!this.morphInto)throw new Error("morphInto not set");e.isBuilding()&&e.buildStatus!==BuildStatus.BuildDown&&this.morphInto.type!==ObjectType.Building&&this.children.push(new PackBuildingTask(this.game)),e.isVehicle()&&this.morphInto.type===ObjectType.Building&&this.children.push(new TurnTask(180))}onTick(t){if(!this.morphInto)throw new Error("morphInto not set");let e=this.game.getUnitSelection();var i=e.isSelected(t),r=e.getOrCreateSelectionModel(t).getControlGroupNumber(),s=this.morphInto;let a;if(s.type===ObjectType.Building){if(t.isVehicle()&&t.parasiteableTrait?.isInfested()&&!t.parasiteableTrait.beingBoarded)return!0;var n=t.tile;let e=this.game.getConstructionWorker(t.owner);if(!e.canPlaceAt(this.morphInto.name,n,{ignoreAdjacent:!0,ignoreObjects:[t]}))return!0;this.game.unspawnObject(t),t.dispose(),[a]=e.placeAt(this.morphInto.name,n),a.healthTrait.health=t.healthTrait.health}else{let e=t.unitOrderTrait.getTasks().filter(e=>e instanceof MoveTask);this.game.unspawnObject(t),t.dispose(),a=this.game.createUnitForPlayer(this.morphInto,t.owner),a.direction=180,a.healthTrait.health=t.healthTrait.health;n=t.art.foundationCenter;this.game.spawnObject(a,this.game.map.tiles.getByMapCoords(t.tile.rx+n.x,t.tile.ry+n.y)),e.forEach(e=>a.unitOrderTrait.addTask(e))}return a.purchaseValue=t.purchaseValue,t.replacedBy=a,i&&e.addToSelection(a),void 0!==r&&e.addUnitsToGroup(r,[a],!1),this.game.events.dispatch(new ObjectMorphEvent(t,a)),!0}}class UndeployIntoTask extends MorphIntoTask{onStart(e){var t=e.rules.undeploysInto;if(!t)throw new Error(`Object type "${e.name}" doesn't undeploy into anything`);this.morphInto=this.game.rules.getObject(t,ObjectType.Vehicle),super.onStart(e)}}class RallyPointChangeEvent{constructor(e){this.target=e,this.type=EventType.RallyPointChange}}class MoveToBlockTask extends Task{constructor(e,t){super(),this.game=e,this.target=t,this.preventOpportunityFire=!1,this.useChildTargetLines=!0,this.attackPerformed=!1}onStart(e){this.children.push(new MoveTask(this.game,this.target.centerTile,!1,{closeEnoughTiles:1,pathFinderIgnoredBlockers:[this.target],stopOnBlocker:this.target}))}onTick(e){if(this.attackPerformed||this.isCancelling()||!e.attackTrait||e.attackTrait.isDisabled())return!0;if(e.moveTrait.lastMoveResult!==MoveResult.CloseEnough)return!0;var t=e.attackTrait.selectWeaponVersus(e,this.target,this.game,!0);return!t||(this.children.push(e.attackTrait.createAttackTask(this.game,this.target,this.target.tile,t,{force:!0})),!(this.attackPerformed=!0))}}const TARGET_UPDATE_TILES=10;class MoveTargetTask extends MoveTask{constructor(e,t){super(e,t.tile,t.onBridge,{forceMove:!0,pathFinderIgnoredBlockers:[t]}),this.target=t,this.tilesSinceTargetUpdate=0}onTick(t){if(!(this.isCancelling()||t.moveTrait.moveState!==MoveState.ReachedNextWaypoint||this.target.tile===this.targetTile&&this.target.onBridge===this.toBridge&&this.target.moveTrait.isIdle())){let e=!1;var i;(t.tile===this.targetTile&&this.target.tile!==this.targetTile||this.tilesSinceTargetUpdate++>TARGET_UPDATE_TILES)&&(e=!0),e&&(this.tilesSinceTargetUpdate=0,(i=this.target.moveTrait.currentWaypoint)?this.updateTarget(i.tile,!!i.onBridge):this.updateTarget(this.target.tile,this.target.onBridge))}return super.onTick(t)}forceCancel(e){return super.forceCancel(e)}getTargetLinesConfig(e){return{target:this.target,pathNodes:[]}}}class MoveOrder extends Order{constructor(e,t,i,r=!1){super(r?OrderType.ForceMove:OrderType.Move),this.game=e,this.map=t,this.unitSelection=i,this.forceMove=r,this.targetOptional=!1,this.feedbackType=OrderFeedbackType.Move}getPointerType(e){let t=this.isAllowed();var i,r,s,a,n;return!t||this.forceMove||this.sourceObject.isBuilding()||this.game.mapShroudTrait.getPlayerShroud(this.sourceObject.owner)?.isShrouded(this.target.tile,this.target.obj?.tileElevation)||(i=!!this.target.getBridge(),r=this.sourceObject.rules.speedType,s=this.sourceObject.isInfantry(),a=this.sourceObject.rules.movementZone===MovementZone.Fly,n=this.map.getObjectsOnTile(this.target.tile).some(e=>(e.isInfantry()||e.isVehicle())&&e.disguiseTrait?.hasTerrainDisguise()),t=a?this.sourceObject.rules.airportBound||this.target.tile.landType===LandType.Cliff||0<this.map.terrain.getPassableSpeed(this.target.tile,SpeedType.Amphibious,!1,i)&&!n:0<this.map.terrain.getPassableSpeed(this.target.tile,r,s,i)&&!n&&!(this.target.obj?.isTechno()&&!this.game.areFriendly(this.target.obj,this.sourceObject))),e?t?PointerType.MoveMini:PointerType.NoActionMini:t?PointerType.Move:PointerType.NoMove}isValid(){return!(this.sourceObject.isBuilding()&&(!this.sourceObject.rules.undeploysInto||this.sourceObject.rules.constructionYard&&!this.game.gameOpts.mcvRepacks)&&!this.sourceObject.rallyTrait?.getRallyPoint())&&(this.forceMove||!this.target.obj||(this.target.obj.isOverlay()||this.target.obj.isBuilding())&&this.target.obj.rules.wall||this.target.obj.isTechno()&&this.target.obj.owner===this.sourceObject.owner&&this.unitSelection.isSelected(this.target.obj)||(this.target.obj.isInfantry()||this.target.obj.isVehicle())&&!!this.target.obj.disguiseTrait?.hasTerrainDisguise()||this.target.obj.isTechno()&&!this.game.areFriendly(this.target.obj,this.sourceObject))}isAllowed(){return(!this.sourceObject.isUnit()||!this.sourceObject.moveTrait.isDisabled())&&(this.game.mapShroudTrait.getPlayerShroud(this.sourceObject.owner)?.isShrouded(this.target.tile,this.target.obj?.tileElevation)?this.sourceObject.rules.moveToShroud:!(!this.forceMove&&this.target.obj?.isTechno()&&this.target.obj.owner===this.sourceObject.owner&&this.unitSelection.isSelected(this.target.obj)))}process(){const e=this.sourceObject;if(!e.isBuilding()||!e.rallyTrait?.getRallyPoint()){var t=this.game.rules.general.closeEnough;return e.isBuilding()&&e.rules.undeploysInto?[new UndeployIntoTask(this.game),new MoveTask(this.game,this.target.tile,!!this.target.getBridge(),{closeEnoughTiles:t,forceMove:this.forceMove})]:e.isUnit()?this.isEnemyBuildingBlock()?[new MoveToBlockTask(this.game,this.target.obj)]:this.isFollowMove()?[new MoveTargetTask(this.game,this.target.obj)]:[new MoveTask(this.game,this.target.tile,!!this.target.getBridge(),{closeEnoughTiles:t,forceMove:this.forceMove})]:void 0}}isEnemyBuildingBlock(){return this.forceMove&&this.sourceObject.isVehicle()&&!this.sourceObject.rules.consideredAircraft&&this.target.obj?.isBuilding()&&!this.game.areFriendly(this.sourceObject,this.target.obj)}isFollowMove(){return this.forceMove&&this.target.obj?.isInfantry()&&this.sourceObject.isVehicle()&&!this.sourceObject.rules.consideredAircraft&&!this.target.obj.moveTrait.isIdle()}onAdd(t,e){var i=this.sourceObject.isBuilding()&&this.sourceObject.rules.undeploysInto;if(i&&this.sourceObject.buildStatus===BuildStatus.BuildUp)return this.sourceObject.unitOrderTrait.getTasks().find(e=>e instanceof WaitForBuildUpTask)?.setCancellable(!0),!0;if(!i&&this.sourceObject.isBuilding()&&this.sourceObject.rallyTrait?.getRallyPoint())return this.sourceObject.rallyTrait.changeRallyPoint(this.target.tile,this.sourceObject,this.game),this.game.events.dispatch(new RallyPointChangeEvent(this.sourceObject)),!1;if(!this.isEnemyBuildingBlock()&&!this.isFollowMove()&&!e&&this.isValid()&&this.isAllowed()){this.sourceObject.attackTrait?.cancelOpportunityFire();let e=t.find(e=>e.constructor===MoveTask&&!e.isCancelling());if(e)return e.setForceMove(this.forceMove),e.updateTarget(this.target.tile,!!this.target.getBridge(),!0),e.children.length&&e.children[0]instanceof AttackTask&&e.children[0].cancel(),t.splice(t.indexOf(e)+1),this.sourceObject.unitOrderTrait.clearOrders(),!1;if(this.sourceObject.isUnit()&&this.sourceObject.rules.movementZone===MovementZone.Fly){let e=t.find(e=>[AttackTask,AttackMoveTask,AttackMoveTargetTask].includes(e.constructor)&&!e.isCancelling());e&&e.forceCancel(this.sourceObject)&&t.splice(t.indexOf(e))}}return!0}}class DeployIntoTask extends MorphIntoTask{onStart(e){var t=e.rules.deploysInto;if(!t)throw new Error(`Object type "${e.name}" doesn't deploy into anything`);this.morphInto=this.game.rules.getObject(t,ObjectType.Building),super.onStart(e)}onTick(e){return!!this.isCancelling()||super.onTick(e)}}class UnitDeployUndeployEvent{constructor(e,t){this.unit=e,this.deployType=t,this.type=EventType.UnitDeployUndeploy}}class PrimaryFactoryChangeEvent{constructor(e){this.target=e,this.type=EventType.PrimaryFactoryChange}}!function(e){e[e.None=0]="None",e[e.OnlyPassengers=1]="OnlyPassengers",e[e.All=2]="All"}(EvacState=EvacState||{});const MAX_EVAC_TRIES=3;class EvacuateTransportTask extends Task{constructor(e,t){super(),this.game=e,this.soft=t,this.evacState=EvacState.None,this.evacTries=0,this.turnPerformed=!1,this.preventLanding=!1}forceEvac(){this.evacState=EvacState.All}onStart(e){if(!e.transportTrait)throw new Error(`Object "${e.name}" is not a valid transport`);var t=e.transportTrait;0<t.units.length&&(this.evacState=this.evacState!==EvacState.OnlyPassengers&&1!==t.units.length||!e.rules.gunner?EvacState.OnlyPassengers:EvacState.All)}onTick(e){if(this.isCancelling()||this.evacState===EvacState.None)return!0;if(e.zone===ZoneType.Air)return this.children.push(new CallbackTask(()=>e.zone!==ZoneType.Air)),!1;let t=e.transportTrait.units;if(!t.length||e.rules.gunner&&1===t.length&&this.evacState!==EvacState.All)return!0;var i=t[t.length-1],r=this.findValidEvacTarget(e,i);if(r&&!this.turnPerformed){this.turnPerformed=!0;var s=(r.dir+180)%360;if(e.direction!==s)return this.children.push(new TurnTask(s)),!1}return this.evacuateUnit(i,e,r)?(t.pop(),this.children.push(new WaitMinutesTask(1/60)),!1):!(++this.evacTries<=MAX_EVAC_TRIES)||(this.children.push(new WaitMinutesTask(.05)),!1)}evacuateUnit(e,t,i){if(!i)return!this.soft&&(e.position.tile=t.tile,e.position.tileElevation=t.tileElevation,e.onBridge=t.onBridge,e.zone=t.zone,this.game.destroyObject(e,{player:e.owner}),!0);var{spawnNode:r,moveNode:i}=i;return e.position.tileElevation=r.onBridge?.tileElevation??0,e.onBridge=!!r.onBridge,e.zone=this.game.map.getTileZone(r.tile,!r.onBridge),this.game.unlimboObject(e,r.tile),e.unitOrderTrait.unmarkNextQueuedOrder(),i?e.unitOrderTrait.addTask(new MoveTask(this.game,i.tile,!!i.onBridge)):e.unitOrderTrait.addTask(new ScatterTask(this.game)),this.game.events.dispatch(new LeaveTransportEvent(t)),!0}findValidEvacTarget(a,n){let o=this.game.map,l=new MovePositionHelper(o);var h,c,d,u,p,t=a.onBridge?o.tileOccupation.getBridgeOnTile(a.tile):void 0,i=(a.direction+180)%360;let g;for(let e=0;e<=180;e+=45)for(h of e&&e<180?[i+e,i-e]:[i+e]){var m=FacingUtil.toMapCoords(h);let i=a.tile,r=t,s;for(let t=1;t<=2;t++){if(2===t){if(!s)break;i=s.tile,r=s.onBridge}var y,T=a.tile.rx+Math.sign(m.x)*t,f=a.tile.ry+Math.sign(m.y)*t,v=o.tiles.getByMapCoords(T,f);if(!v||!o.mapBounds.isWithinBounds(v))break;let e=[o.tileOccupation.getBridgeOnTile(v)];e[0]&&e.push(void 0);for(y of e)if(c=v,d=y,u=r,p=i,0<o.terrain.getPassableSpeed(c,n.rules.speedType,n.isInfantry(),!!d)&&l.isEligibleTile(c,d,u,p)&&!o.terrain.findObstacles({tile:c,onBridge:d},n).length){if(1!==t)return{spawnNode:s,moveNode:{tile:v,onBridge:y},dir:h};s={tile:v,onBridge:y},g={spawnNode:s,moveNode:void 0,dir:h}}}}if(g)return g}}class DeployOrder extends Order{constructor(e,t){super(t?OrderType.Deploy:OrderType.DeploySelected),this.game=e,this.targeted=t,this.minimapAllowed=!1,this.getPointerType=()=>this.isAllowed()?PointerType.Deploy:PointerType.NoDeploy,this.targetOptional=!t,this.singleSelectionRequired=t}isValid(){if(this.targeted&&(!this.target.obj||this.target.obj!==this.sourceObject))return!1;let e=this.sourceObject;return!!(e.isInfantry()&&e.deployerTrait&&![StanceType.Cheer].includes(e.stance)||e.isVehicle()&&e.deployerTrait||e.isVehicle()&&e.rules.deploysInto||e.isVehicle()&&e.transportTrait||e.isBuilding()&&e.rules.factory&&!e.owner.production?.isPrimaryFactory(e)||e.isBuilding()&&e.garrisonTrait?.units.length)}isAllowed(){let t=this.sourceObject;if(t.isVehicle()&&t.transportTrait)return!!(t.transportTrait.units.length&&0<this.game.map.terrain.getPassableSpeed(t.tile,SpeedType.Foot,!1,t.onBridge));if((t.isInfantry()||t.isVehicle())&&t.deployerTrait)return!0;if(t.isVehicle()&&t.rules.deploysInto){if(t.parasiteableTrait?.isInfested()&&!t.parasiteableTrait.beingBoarded)return!1;let e=this.game.getConstructionWorker(t.owner);if(t.moveTrait.currentWaypoint?.onBridge)return!1;var i=t.moveTrait.currentWaypoint?.tile??t.tile;return e.canPlaceAt(t.rules.deploysInto,i,{ignoreObjects:[t],ignoreAdjacent:!0})}if(t.isBuilding()&&t.rules.factory)return!0;if(t.isBuilding()&&t.garrisonTrait?.units.length)return!0;throw new Error("Shouldn't reach this point. Missed a case.")}process(){const e=this.sourceObject;return e.isVehicle()&&e.transportTrait?[new EvacuateTransportTask(this.game,!0)]:e.isBuilding()&&e.rules.factory?void 0:e.isVehicle()&&e.rules.deploysInto?[new DeployIntoTask(this.game)]:(e.isInfantry()||e.isVehicle())&&e.deployerTrait?[new CallbackTask(()=>{e.deployerTrait.toggleDeployed(),this.game.events.dispatch(new UnitDeployUndeployEvent(e,e.deployerTrait.isDeployed()?"undeploy":"deploy"))})]:e.isBuilding()&&e.garrisonTrait?.units.length?[new CallbackTask(()=>{e.garrisonTrait.evacuate(this.game,!0)})]:void 0}onAdd(t,e){let i=this.sourceObject;if(i.isBuilding()&&i.rules.factory)return i.owner.production.setPrimaryFactory(i),this.game.events.dispatch(new PrimaryFactoryChangeEvent(i)),!1;if(i.isVehicle()&&i.transportTrait&&!e&&this.isValid()&&this.isAllowed()){let e=t.find(e=>e.constructor===EvacuateTransportTask&&!e.isCancelling());if(e)return e.forceEvac(),!1}return!0}}class CheerEvent{constructor(e){this.player=e,this.type=EventType.Cheer}}class DeployNotAllowedEvent{constructor(e){this.target=e,this.type=EventType.DeployNotAllowed}}const ORDER_UNIT_LIMIT=128;class OrderUnitsAction extends Action{constructor(e,t,i,r){super(ActionType.OrderUnits),this.game=e,this.map=t,this.orderActionContext=i,this.orderFactory=r,this.queue=!1,this.isInvalid=!1}unserialize(t){let i=new DataStream(t);this.orderType=i.readUint8();var r=i.readUint8();if(0!==r){var s=i.readUint16(),t=i.readUint16();this.queue=2<r&&Boolean(i.readUint8());let e;if(3<r){r=i.readUint32();if(!this.game.getWorld().hasObjectId(r))return void(this.isInvalid=!0);e=this.game.getObjectById(r)}else e=void 0;t=this.map.tiles.getByMapCoords(s,t);t?this.target=this.game.createTarget(e,t):this.isInvalid=!0}}serialize(){let e=new DataStream(11);e.dynamicSize=!1,e.writeUint8(this.orderType);let t=0;e.writeUint8(t),this.target&&(e.writeUint16(this.target.tile.rx),e.writeUint16(this.target.tile.ry),t+=2,i=(this.target.obj||this.target.getBridge())?.id,!this.queue&&void 0===i||(e.writeUint8(Number(this.queue)),t+=1),void 0!==i&&(e.writeUint32(i),t+=1));var i=e.position;return 0<t&&(e.seek(1),e.writeUint8(t)),new Uint8Array(e.buffer,e.byteOffset,i)}print(){return this.isInvalid?"":OrderType[this.orderType]+" order "+(this.target?`[obj: ${(this.target.obj||this.target.getBridge())?.name||"<none>"}, `+`tile: ${this.target.tile.rx},${this.target.tile.ry}]`+(this.queue?"(queue)":""):"")}process(){if(!this.isInvalid){let n=this.player;const c=this.game.mapShroudTrait.getPlayerShroud(n);if(c){const d=this.target?.obj;if(d){let e=this.game.map.tileOccupation.calculateTilesForGameObject(d.tile,d);if(!e.find(e=>!c.isShrouded(e,d.tileElevation)))return}let e=this.validateOrders(n).slice(0,ORDER_UNIT_LIMIT),a=[],t=[],r=[],i=[],s=[];if(e.forEach(e=>{(e instanceof MoveOrder?t:e.orderType===OrderType.Scatter?r:e.orderType===OrderType.DeploySelected?i:e.orderType===OrderType.Cheer?s:a).push(e)}),t.length&&this.target){var o=t[0].isEnemyBuildingBlock(),l=t[0].isFollowMove();if(o||l)t.forEach(e=>a.push(e));else{let r=this.target.getBridge();var h=t[0].forceMove,l=t.map(e=>e.sourceObject);let s=new MovePositionHelper(this.map).findPositions(l,this.target.tile,r,h);t.forEach(e=>{var t=s.get(e.sourceObject),i=!r||r.isHighBridge()?this.map.tileOccupation.getBridgeOnTile(t):r,t=this.game.createTarget(i,t);e.target=t,a.push(e)})}}if(r.length){h=r.map(e=>e.sourceObject).filter(e=>e.isInfantry()||e.isVehicle());let i=new ScatterPositionHelper(this.game).findPositions(h);r.forEach(e=>{var t=i.get(e.sourceObject);t&&(t=this.game.createTarget(t.onBridge,t.tile),e.target=t,a.push(e))})}if(i.length){let t=[];i.forEach(e=>{((e.sourceObject.isInfantry()||e.sourceObject.isVehicle())&&e.sourceObject.deployerTrait?t:a).push(e)});let e=t.filter(e=>!e.sourceObject.deployerTrait.isDeployed());e.length?e.forEach(e=>a.push(e)):t.forEach(e=>a.push(e))}s.length&&(n.cheerCooldownTicks||(n.cheerCooldownTicks=this.game.rules.general.maximumCheerRate,a.push(...s),this.game.events.dispatch(new CheerEvent(n)))),a.forEach(e=>e.sourceObject.unitOrderTrait.addOrder(e,this.queue)),this.updateWaypointPaths(a)}}}validateOrders(e){let i=this.orderActionContext.getOrCreateSelection(e);var r,s=i.getSelectedUnits();let t=this.orderFactory.create(this.orderType,i);t.target=this.target;let a=[];for(r of s)if(!(r.owner!==e||r.rules.spawned||r.isDestroyed||r.isCrashing||r.isDisposed||r.warpedOutTrait.isActive()||(t.sourceObject=r,t instanceof DeployOrder&&t.isValid()&&!t.isAllowed()&&this.game.events.dispatch(new DeployNotAllowedEvent(r)),t.singleSelectionRequired&&1<s.length)))if(t.isValid()&&t.isAllowed()){let e=this.orderFactory.create(this.orderType,i);e.set(r,this.target),a.push(e)}else{let t=!1;for(var n of orderPriorities){let e=this.orderFactory.create(n,i);if(e.set(r,this.target),!(e.singleSelectionRequired&&1<s.length)&&(e.targetOptional===!this.target&&e.isValid()&&e.isAllowed())){a.push(e),t=!0;break}}if(!t&&this.target&&this.orderType!==OrderType.Deploy){let e=this.orderFactory.create(OrderType.Move,i);e.set(r,this.target),e.isValid()&&e.isAllowed()&&a.push(e)}}return a}updateWaypointPaths(i){if(this.queue&&this.target){let e=i.map(e=>e.sourceObject);var t=[...new Set(e.map(e=>e.unitOrderTrait.waypointPath).filter(isNotNullOrUndefined))];if(t.length<=1){i={orderType:this.orderType,target:this.target,terminal:i.some(e=>e.terminal),next:void 0};if(0===t.length){let t={units:e,waypoints:[i]};e.forEach(e=>{e.unitOrderTrait.waypointPath=t})}else{let e=t[0];e.waypoints[e.waypoints.length-1].next=i,e.waypoints.push(i)}}}}}class SelectUnitsAction extends Action{get unitIds(){return this._unitIds}set unitIds(e){this._unitIds=e.slice(0,ORDER_UNIT_LIMIT)}constructor(e,t){super(ActionType.SelectUnits),this.game=e,this.orderActionContext=t}unserialize(t){let i=new DataStream(t);this.unitIds=new Array(t.byteLength/4);for(let e=0;e<t.byteLength/4;e++)this.unitIds[e]=i.readUint32()}serialize(){let e=new DataStream(4*this.unitIds.length);e.dynamicSize=!1;for(var t of this.unitIds)e.writeUint32(t);return e.toUint8Array()}print(){return`Select unit(s) [${this.unitIds.join(",")}]`}process(){let e=this.player,i=[];for(var r of this.unitIds){let t=e.getOwnedObjectById(r);if(!t&&this.game.getWorld().hasObjectId(r)){let e=this.game.getWorld().getObjectById(r);e.isTechno()&&(t=e)}t&&i.push(t)}this.orderActionContext.getOrCreateSelection(e).update(i)}}class SelectUnitsActionFactory{constructor(e,t){this.game=e,this.orderActionContext=t}create(){return new SelectUnitsAction(this.game,this.orderActionContext)}}class BuildingGarrisonEvent{constructor(e){this.target=e,this.type=EventType.BuildingGarrison}}class MoveOutsideTask extends MoveTask{constructor(e,t,i){super(e,i??t.tile,!1,{ignoredBlockers:[t]}),this.target=t,this.cancellable=!1}canStopAtTile(e,t,i){return!this.game.map.tileOccupation.isTileOccupiedBy(t,this.target)&&super.canStopAtTile(e,t,i)}}class MoveInsideTask extends MoveTask{static chooseTargetFoundationTile(t,i){if(t.isBuilding()){let e=t.centerTile;return i.map.mapBounds.isWithinBounds(e)||(e=i.map.tileOccupation.calculateTilesForGameObject(t.tile,t).find(e=>i.map.mapBounds.isWithinBounds(e))??t.tile),e}return t.tile}constructor(e,t){super(e,MoveInsideTask.chooseTargetFoundationTile(t,e),!1,{ignoredBlockers:[t],closeEnoughTiles:0}),this.target=t}hasReachedDestination(e){return super.hasReachedDestination(e)||this.canStopAtTile(e,e.tile,e.onBridge)}canStopAtTile(e,t,i){t=this.game.map.tileOccupation.isTileOccupiedBy(t,this.target);return(!this.isCancelling()||!t)&&!(!this.isCancelling()&&!t)}isCloseEnoughToDest(e,t,i){return this.game.map.tileOccupation.isTileOccupiedBy(t,this.target)}}class EnterObjectEvent{constructor(e,t){this.target=e,this.source=t,this.type=EventType.EnterObject}}class EnterBuildingTask extends Task{constructor(e,t){super(),this.game=e,this.target=t,this.aborted=!1,this.movePerformed=!1,this.preventOpportunityFire=!1}onTick(e){return!!(this.isCancelling()&&!this.movePerformed||this.aborted||e.moveTrait.isDisabled())||(this.movePerformed&&this.children.length?(e.tile===this.lastOutsideTile||this.game.map.tileOccupation.isTileOccupiedBy(e.tile,this.target)||(this.lastOutsideTile=e.tile),!1):this.game.map.tileOccupation.isTileOccupiedBy(e.tile,this.target)?!this.isAllowed(e)||this.isCancelling()?(this.children.push(new MoveOutsideTask(this.game,this.target,this.lastOutsideTile)),!(this.aborted=!0)):(this.game.events.dispatch(new EnterObjectEvent(this.target,e)),!1!==this.onEnter(e)||(this.children.push(new MoveOutsideTask(this.game,this.target,this.lastOutsideTile)),!(this.aborted=!0))):!!this.movePerformed||(this.children.push(new MoveInsideTask(this.game,this.target).setBlocking(!1)),this.movePerformed=!0,!(this.preventOpportunityFire=!0)))}getTargetLinesConfig(e){return{target:this.target,pathNodes:[]}}}class GarrisonBuildingTask extends EnterBuildingTask{isAllowed(e){return!this.target.isDestroyed&&!!this.target.garrisonTrait?.canBeOccupied()&&this.target.garrisonTrait.units.length<this.target.garrisonTrait.maxOccupants&&!(this.target.garrisonTrait.units.length&&this.target.garrisonTrait.units[0].owner!==e.owner)&&!e.mindControllableTrait?.isActive()}onEnter(e){this.game.limboObject(e,{selected:!1,controlGroup:this.game.getUnitSelection().getOrCreateSelectionModel(e).getControlGroupNumber()});let t=this.target.garrisonTrait;t.units.length||(e.owner.buildingsCaptured++,this.game.changeObjectOwner(this.target,e.owner),this.game.events.dispatch(new BuildingGarrisonEvent(this.target))),t.units.push(e)}}class UnitRecycleEvent{constructor(e){this.target=e,this.type=EventType.UnitRecycle}}class EnterRecyclerTask extends EnterBuildingTask{isAllowed(e){return e.rules.movementZone!==MovementZone.Fly&&e.rules.locomotor!==LocomotorType.Chrono&&!e.rules.engineer&&0<this.game.sellTrait.computeRefundValue(e)&&(e.isInfantry()&&this.target.rules.cloning||this.target.rules.grinding)&&!this.target.isDestroyed&&this.target.buildStatus===BuildStatus.Ready&&e.owner===this.target.owner}onEnter(e){this.game.sellTrait.sell(e),this.game.events.dispatch(new UnitRecycleEvent(e))}}class BuildingInfiltrationEvent{constructor(e,t){this.target=e,this.source=t,this.type=EventType.BuildingInfiltration}}class InfiltrateBuildingTask extends EnterBuildingTask{isAllowed(e){return e.rules.infiltrate&&this.target.rules.spyable&&!this.target.isDestroyed&&!this.game.areFriendly(e,this.target)}onEnter(e){this.game.unspawnObject(e),e.agentTrait?.infiltrate(e,this.target,this.game),this.game.events.dispatch(new BuildingInfiltrationEvent(this.target,e))}}!function(e){e[e.MoveToQueueingTile=0]="MoveToQueueingTile",e[e.WaitForTurn=1]="WaitForTurn",e[e.MoveToTarget=2]="MoveToTarget",e[e.EnterTarget=3]="EnterTarget",e[e.ClearTarget=4]="ClearTarget"}(EnterHospitalTask_State=EnterHospitalTask_State||{});class EnterHospitalTask extends Task{constructor(e,t){super(),this.game=e,this.target=t,this.movePerformed=!1}isAllowed(e){return e.rules.movementZone!==MovementZone.Fly&&e.healthTrait.health<100&&this.target.hospitalTrait&&!this.target.isDestroyed&&!this.target.warpedOutTrait.isActive()&&this.game.areFriendly(e,this.target)&&(!this.target.ammoTrait||0<this.target.ammoTrait.ammo)}onStart(e){if(!this.target.hospitalTrait)throw new Error(`Target ${this.target.name} is not a valid hospital`);0<this.target.hospitalTrait.addToHealQueue(e)?this.state=EnterHospitalTask_State.MoveToQueueingTile:this.state=EnterHospitalTask_State.MoveToTarget}onEnd(e){!this.target.isDestroyed&&e.isSpawned&&this.target.hospitalTrait.removeFromHealQueue(e)}onTick(i){if(this.isCancelling()&&this.state!==EnterHospitalTask_State.EnterTarget||this.state===EnterHospitalTask_State.ClearTarget||i.moveTrait.isDisabled())return!0;if(this.state===EnterHospitalTask_State.MoveToQueueingTile){let t=new MovePositionHelper(this.game.map);var e=new RadialTileFinder(this.game.map.tiles,this.game.map.mapBounds,this.target.tile,this.target.getFoundation(),1,1,e=>0<this.game.map.terrain.getPassableSpeed(e,i.rules.speedType,i.isInfantry(),!1)&&t.isEligibleTile(e,void 0,void 0,this.target.tile)).getNextTile();return!e||(this.children.push(new MoveTask(this.game,e,!1,{closeEnoughTiles:5})),this.children.push(new CallbackTask(()=>{[MoveResult.Success,MoveResult.CloseEnough].includes(i.moveTrait.lastMoveResult)||this.cancel()})),this.state=EnterHospitalTask_State.WaitForTurn,this.queueingTile=e,!1)}if(this.state===EnterHospitalTask_State.WaitForTurn){if(!this.target.hospitalTrait.unitIsFirstInHealQueue(i))return!1;this.queueingTile=void 0,this.state=EnterHospitalTask_State.MoveToTarget}if(this.state===EnterHospitalTask_State.MoveToTarget){if(this.movePerformed&&this.children.length)return i.tile===this.lastOutsideTile||this.game.map.tileOccupation.isTileOccupiedBy(i.tile,this.target)||(this.lastOutsideTile=i.tile),!1;if(!this.isAllowed(i))return!0;if(!this.game.map.tileOccupation.isTileOccupiedBy(i.tile,this.target))return!!this.movePerformed||(this.children.push(new MoveInsideTask(this.game,this.target).setBlocking(!1)),!(this.movePerformed=!0));this.state=EnterHospitalTask_State.EnterTarget}return this.state===EnterHospitalTask_State.EnterTarget&&(!this.isAllowed(i)||this.isCancelling()?(this.children.push(new MoveOutsideTask(this.game,this.target,this.lastOutsideTile)),this.state=EnterHospitalTask_State.ClearTarget,!1):(this.game.limboObject(i,{selected:!1,controlGroup:this.game.getUnitSelection().getOrCreateSelectionModel(i).getControlGroupNumber()}),this.target.hospitalTrait.startHealing(i),this.game.events.dispatch(new EnterObjectEvent(this.target,i)),!0))}getTargetLinesConfig(e){return{target:this.queueingTile?void 0:this.target,pathNodes:this.queueingTile?[{tile:this.queueingTile,onBridge:void 0}]:[]}}}class OccupyOrder extends Order{constructor(e){super(OrderType.Occupy),this.game=e,this.targetOptional=!1,this.terminal=!0,this.feedbackType=OrderFeedbackType.Capture}getPointerType(e){return e?this.isAllowed()?PointerType.OccupyMini:PointerType.NoActionMini:this.isAllowed()?PointerType.Occupy:PointerType.NoOccupy}isValid(){return!!(this.target.obj?.isSpawned&&this.target.obj?.isBuilding()&&this.sourceObject.isUnit())&&(!!this.isUnitRecycle(this.sourceObject,this.target.obj)||!!this.sourceObject.isInfantry()&&(this.target.obj.isBuilding()&&this.target.obj.hospitalTrait?this.game.areFriendly(this.sourceObject,this.target.obj)&&this.sourceObject.isInfantry():this.target.obj.garrisonTrait?this.target.obj.garrisonTrait.canBeOccupied()&&this.sourceObject.rules.occupier&&!(this.target.obj.garrisonTrait.units.length&&this.target.obj.garrisonTrait.units[0].owner!==this.sourceObject.owner)&&!this.sourceObject.mindControllableTrait?.isActive()&&!this.sourceObject.mindControllerTrait?.isActive():!(!this.target.obj.rules.spyable||!this.sourceObject.rules.infiltrate||this.game.areFriendly(this.sourceObject,this.target.obj))))}isUnitRecycle(e,t){return e.owner===t.owner&&(e.isInfantry()&&t.rules.cloning||t.rules.grinding)&&!e.rules.engineer}isAllowed(){var e=this.target.obj,t=this.sourceObject;return this.isUnitRecycle(t,e)?t.rules.movementZone!==MovementZone.Fly&&t.rules.locomotor!==LocomotorType.Chrono&&0<this.game.sellTrait.computeRefundValue(t):e.hospitalTrait?t.healthTrait.health<100&&t.rules.movementZone!==MovementZone.Fly:!e.garrisonTrait||e.garrisonTrait.units.length<e.rules.maxNumberOccupants}process(){var e=this.target.obj,t=this.sourceObject;return this.isUnitRecycle(t,e)?[new EnterRecyclerTask(this.game,e)]:e.hospitalTrait?[new EnterHospitalTask(this.game,e)]:e.garrisonTrait?[new GarrisonBuildingTask(this.game,e)]:[new InfiltrateBuildingTask(this.game,e)]}onAdd(t,e){if(!e){let e=t.find(e=>e instanceof GarrisonBuildingTask||e instanceof InfiltrateBuildingTask);if(this.isValid()&&this.isAllowed()&&e&&!e.isCancelling()&&e.target===this.target.obj)if(new RangeHelper(this.game.map.tileOccupation).isInTileRange(this.sourceObject,this.target.obj,0,Math.SQRT2))return!1}return!0}}class PlantC4Task extends EnterBuildingTask{isAllowed(e){return!this.target.isDestroyed&&!this.target.invulnerableTrait.isActive()}onEnter(e){var t=Math.floor(60*this.game.rules.combatDamage.c4Delay*GameSpeed.BASE_TICKS_PER_SECOND);return this.target.c4ChargeTrait.setCharge(t,{player:e.owner,obj:e}),this.game.events.dispatch(new EnterObjectEvent(this.target,e)),!1}getTargetLinesConfig(e){return{target:this.target,pathNodes:[],isAttack:!0}}}class AttackOrder extends Order{constructor(e,{forceAttack:t,noIvanBomb:i}={}){super(t?OrderType.ForceAttack:OrderType.Attack),this.game=e,this.isC4=!1,this.forceAttack=!!t,this.ivanBombAllowed=!i||!!t,this.targetOptional=!1,this.feedbackType=OrderFeedbackType.None,this.rangeHelper=new RangeHelper(this.game.map.tileOccupation),this.losHelper=new LosHelper(this.game.map.tiles,e.map.tileOccupation)}getPointerType(e,t){if(!this.isAllowed())return e?PointerType.NoActionMini:PointerType.NoAction;if(this.isC4)return PointerType.C4;var i=this.sourceObject.attackTrait?.selectWeaponVersus(this.sourceObject,this.target,this.game,this.forceAttack);if(i?.rules.sabotageCursor)return PointerType.C4;if(this.ivanBombAllowed&&this.sourceObject.rules.ivan&&i?.warhead.rules.ivanBomb)return PointerType.Dynamite;if(i?.warhead.rules.bombDisarm)return PointerType.DefuseBomb;if(i&&i.rules.damage<0)return PointerType.RepairMove;t=t.every(e=>{if(!e.attackTrait)return!0;var t=e.attackTrait.selectWeaponVersus(e,this.target,this.game,this.forceAttack);return!t||this.rangeHelper.isInWeaponRange(e,this.target.obj||this.target.tile,t,this.game.rules)&&this.losHelper.hasLineOfSight(e,this.target.obj||this.target.tile,t)});return e?PointerType.AttackMini:t?PointerType.AttackRange:PointerType.AttackNoRange}isValid(){if(!this.sourceObject.attackTrait)return!1;if(this.forceAttack&&this.game.mapShroudTrait.getPlayerShroud(this.sourceObject.owner)?.isShrouded(this.target.tile,this.target.obj?.tileElevation)&&!this.sourceObject.isBuilding())return!1;let e=this.target.obj;var t=this.game.map.getGroundObjectsOnTile(this.target.tile).find(e=>e.isTerrain());if(this.terminal=!e&&!t,this.sourceObject.c4&&e?.isBuilding()&&e.c4ChargeTrait&&(this.forceAttack||!this.game.areFriendly(e,this.sourceObject)||e.cabHutTrait))return this.isC4=!0,this.feedbackType=OrderFeedbackType.SpecialAttack,!0;if(this.isC4=!1,this.feedbackType=OrderFeedbackType.Attack,!this.game.isValidTarget(e))return!1;if(!e&&t?.rules.immune)return!1;if(!(e||this.target.tile!==this.sourceObject.tile||this.sourceObject.isUnit()&&this.sourceObject.zone===ZoneType.Air))return!1;if(e===this.sourceObject)return!1;t=this.sourceObject.attackTrait.selectWeaponVersus(this.sourceObject,this.target,this.game,this.forceAttack);return!!t&&(!(!this.ivanBombAllowed&&t.warhead.rules.ivanBomb)&&(!(e?.isBuilding()&&e.cabHutTrait&&!t.warhead.rules.ivanBomb&&!t.warhead.rules.bombDisarm)&&(!!(this.sourceObject.isUnit()&&this.sourceObject.moveTrait&&!this.sourceObject.moveTrait.isDisabled()||this.rangeHelper.isInWeaponRange(this.sourceObject,e||this.target.tile,t,this.game.rules))&&(!(this.sourceObject.airSpawnTrait&&t.rules.spawner&&!this.game.map.isWithinBounds(this.target.tile))&&(!!this.forceAttack||(!e?.isBuilding()||!e.hospitalTrait)&&(!(!e||!e.healthTrait)&&(!e.isDestroyed&&!e.isCrashing&&(!(!e.isOverlay()||!(t.warhead.rules.wall||t.warhead.rules.wood&&e.rules.armor===ArmorType.Wood))||e.isTechno()))))))))}isAllowed(){return!this.sourceObject.attackTrait.isDisabled()}process(){if(this.isC4)return[new PlantC4Task(this.game,this.target.obj)];var e=this.sourceObject.attackTrait.selectWeaponVersus(this.sourceObject,this.target,this.game,this.forceAttack);return[new AttackTask(this.game,this.target,e,{force:this.forceAttack})]}onAdd(t,i){let r=this.sourceObject;if(!i&&r.isUnit()&&this.isValid()&&this.isAllowed())if(r.rules.movementZone===MovementZone.Fly){var s=t.find(e=>(e.constructor===MoveTask||e.constructor===AttackTask)&&!e.isCancelling());let e;s&&(r.moveTrait.currentWaypoint?.tile===this.target.tile||r.isAircraft()||s.constructor===AttackTask||(i=this.sourceObject.attackTrait.selectWeaponVersus(this.sourceObject,this.target,this.game,this.forceAttack)).projectileRules.vertical&&s.constructor===MoveTask&&this.rangeHelper.isInWeaponRange(this.sourceObject,this.target.obj||this.target.tile,i,this.game.rules))&&(e=s),e?.forceCancel(r)&&t.splice(t.indexOf(e))}else{t.length&&r.isUnit()&&(r.rules.locomotor===LocomotorType.Vehicle||r.rules.locomotor===LocomotorType.Ship)&&(r.moveTrait.speedPenalty=.5);let e=t.find(e=>e.constructor===AttackTask&&!e.isCancelling());if(e?.getWeapon().warhead.rules.temporal)return e.setForceAttack(this.forceAttack),e.requestTargetUpdate(this.target),!1}return!0}}class StopOrder extends Order{constructor(e){super(OrderType.Stop),this.game=e,this.getPointerType=()=>PointerType.NoAction}isValid(){return this.sourceObject.isTechno()}isAllowed(){return!0}process(){return[new CallbackTask(e=>{!e.isUnit()||e.rules.locomotor!==LocomotorType.Vehicle&&e.rules.locomotor!==LocomotorType.Ship||(e.moveTrait.speedPenalty=0)})]}onAdd(e,t){let i=this.sourceObject;return t||!e.length||!i.isUnit()||i.rules.locomotor!==LocomotorType.Vehicle&&i.rules.locomotor!==LocomotorType.Ship||(i.moveTrait.speedPenalty=.5),i.isBuilding()&&i.rallyTrait?.getRallyPoint()&&(i.unitRepairTrait?.resetRallyPoint(i,this.game),i.factoryTrait?.resetRallyPoint(i,this.game)),!0}}class CheerOrder extends Order{constructor(){super(OrderType.Cheer),this.getPointerType=()=>PointerType.NoAction}isValid(){return this.sourceObject.isInfantry()&&[StanceType.None,StanceType.Guard].includes(this.sourceObject.stance)}isAllowed(){return!0}process(){return[new CheerTask]}}class DockOrder extends Order{constructor(e){super(OrderType.Dock),this.game=e,this.targetOptional=!1,this.feedbackType=OrderFeedbackType.Move}getPointerType(e){return e?this.isAllowed()?PointerType.OccupyMini:PointerType.NoActionMini:this.isAllowed()?PointerType.Occupy:PointerType.NoOccupy}isValid(){if(!this.target.obj?.isBuilding()||this.target.obj.isDestroyed||!this.target.obj.dockTrait||this.target.obj.buildStatus!==BuildStatus.Ready||!this.sourceObject.isUnit()||this.target.obj.warpedOutTrait.isActive())return!1;var e=!(this.target.obj.rules.refinery||this.target.obj.unitRepairTrait);return this.game.areFriendly(this.target.obj,this.sourceObject)&&this.target.obj.dockTrait.isValidUnitForDock(this.sourceObject)&&!this.target.obj.dockTrait.isDocked(this.sourceObject)&&!(this.target.obj.unitRepairTrait&&!this.sourceObject.rules.dock.includes(this.target.obj.name)&&100===this.sourceObject.healthTrait.health)&&(!e||(0<(this.target.obj.dockTrait.getAvailableDockCount()??0)||this.target.obj.dockTrait.hasReservedDockForUnit(this.sourceObject)))}isAllowed(){return!0}process(){var e=this.target.obj;return e.rules.refinery&&this.sourceObject.isVehicle()&&this.sourceObject.harvesterTrait?[new ReturnOreTask(this.game,e,!0,!0)]:e.unitRepairTrait||this.sourceObject.rules.dock.includes(e.name)?[new MoveToDockTask(this.game,e)]:[]}}class GatherOrder extends Order{constructor(e){super(OrderType.Gather),this.game=e,this.targetOptional=!1,this.feedbackType=OrderFeedbackType.Move}getPointerType(e){return e?PointerType.AttackMini:PointerType.AttackNoRange}isValid(){return!(!this.sourceObject.isVehicle()||!this.sourceObject.harvesterTrait||this.sourceObject.moveTrait.isDisabled()||this.game.mapShroudTrait.getPlayerShroud(this.sourceObject.owner)?.isShrouded(this.target.tile,this.target.obj?.tileElevation))&&this.target.isOre}isAllowed(){return!0}process(){return[new GatherOreTask(this.game,this.target.tile,!0)]}}class AttackMoveOrder extends AttackOrder{constructor(e,t){super(e),this.map=t,this.orderType=OrderType.AttackMove,this.targetOptional=!1,this.feedbackType=OrderFeedbackType.Move}getPointerType(t,i){if(this.isTargetted()){let e=super.getPointerType(t,i);return e!==PointerType.AttackRange&&e!==PointerType.AttackNoRange||(e=PointerType.AttackMove),e}let e=this.isAllowed();var r,s,a;return e&&(r=!!this.target.getBridge(),s=this.sourceObject.rules.speedType,a=this.sourceObject.isInfantry(),i=this.sourceObject.rules.movementZone===MovementZone.Fly,e=i||0<this.map.terrain.getPassableSpeed(this.target.tile,s,a,r)||!!this.game.mapShroudTrait.getPlayerShroud(this.sourceObject.owner)?.isShrouded(this.target.tile,this.target.obj?.tileElevation)),t?e?PointerType.AttackMini:PointerType.NoActionMini:e?PointerType.AttackMove:PointerType.NoMove}isValid(){var e=this.sourceObject.isUnit()&&!!this.sourceObject.attackTrait&&!this.sourceObject.rules.preventAttackMove&&!(this.game.mapShroudTrait.getPlayerShroud(this.sourceObject.owner)?.isShrouded(this.target.tile,this.target.obj?.tileElevation)&&!this.sourceObject.rules.moveToShroud)&&(!this.isTargetted()||super.isValid());return this.feedbackType=OrderFeedbackType.Move,e}isAllowed(){return!(!this.isTargetted()&&this.sourceObject.moveTrait.isDisabled())&&super.isAllowed()}process(){if(this.isTargetted()){if(this.isC4)return[new PlantC4Task(this.game,this.target.obj)];var e=this.sourceObject.attackTrait.selectWeaponVersus(this.sourceObject,this.target,this.game);return[new AttackMoveTargetTask(this.game,this.target,e)]}return[new AttackMoveTask(this.game,this.target.tile,!!this.target.getBridge(),{closeEnoughTiles:this.game.rules.general.closeEnough})]}isTargetted(){return this.target.obj?.isTechno()}onAdd(t,e){let i=this.sourceObject;if(!e&&i.isUnit()&&this.isValid()&&this.isAllowed())if(i.rules.movementZone===MovementZone.Fly){let e=t.find(e=>[MoveTask,AttackTask,AttackMoveTask,AttackMoveTargetTask].includes(e.constructor)&&!e.isCancelling());if(e)if(this.isTargetted())(i.moveTrait.currentWaypoint?.tile===this.target.tile||i.isAircraft()||e.constructor!==MoveTask)&&e.forceCancel(i)&&t.splice(t.indexOf(e));else{if(e.constructor===AttackMoveTask)return e.updateTarget(this.target.tile,!!this.target.getBridge()),t.splice(t.indexOf(e)+1),i.unitOrderTrait.clearOrders(),!1;e.forceCancel(i)&&t.splice(t.indexOf(e))}}else this.isTargetted()&&t.length&&i.isUnit()&&(i.rules.locomotor===LocomotorType.Vehicle||i.rules.locomotor===LocomotorType.Ship)&&(i.moveTrait.speedPenalty=.5);return!0}}class BuildingRepairFullEvent{constructor(e,t){this.target=e,this.source=t,this.type=EventType.BuildingRepairFull}}class BridgeRepairEvent{constructor(e,t){this.source=e,this.tile=t,this.type=EventType.BridgeRepair}}class RepairBuildingTask extends EnterBuildingTask{isAllowed(e){return this.target.cabHutTrait?this.target.cabHutTrait.canRepairBridge():e.rules.engineer&&!this.target.isDestroyed&&this.target.rules.repairable&&this.target.healthTrait.health<100&&(!this.target.owner.isCombatant()&&!!this.target.garrisonTrait||this.game.areFriendly(e,this.target))}onEnter(e){this.game.unspawnObject(e),this.target.cabHutTrait?(this.target.cabHutTrait.repairBridge(this.game,e.owner),this.game.events.dispatch(new BridgeRepairEvent(e.owner,this.target.centerTile))):(this.target.healthTrait.healToFull(e,this.game),this.game.events.dispatch(new BuildingRepairFullEvent(this.target,e.owner)))}}class RepairOrder extends Order{constructor(e){super(OrderType.Repair),this.game=e,this.targetOptional=!1,this.terminal=!0,this.feedbackType=OrderFeedbackType.Capture}getPointerType(e){return e?this.isAllowed()?PointerType.OccupyMini:PointerType.NoActionMini:this.isAllowed()?PointerType.RepairMove:PointerType.NoRepair}isValid(){return!!this.target.obj?.isBuilding()&&!this.target.obj.isDestroyed&&this.sourceObject.isInfantry()&&this.sourceObject.rules.engineer&&(!this.target.obj.owner.isCombatant()&&(!!this.target.obj.garrisonTrait||!!this.target.obj.cabHutTrait)||this.game.areFriendly(this.target.obj,this.sourceObject))}isAllowed(){let e=this.target.obj;return e.cabHutTrait?e.cabHutTrait.canRepairBridge():!!(e.rules.repairable&&e.healthTrait.health<100)}process(){var e=this.target.obj;return[new RepairBuildingTask(this.game,e)]}onAdd(t,e){if(!e){let e=t.find(e=>e instanceof RepairBuildingTask);if(this.isValid()&&this.isAllowed()&&e&&!e.isCancelling()&&e.target===this.target.obj)if(new RangeHelper(this.game.map.tileOccupation).isInTileRange(this.sourceObject,this.target.obj,0,Math.SQRT2))return!1}return!0}}class GuardAreaOrder extends Order{constructor(e,t){super(t?OrderType.GuardArea:OrderType.Guard),this.game=e,this.targeted=t,this.getPointerType=e=>e?this.isAllowed()?PointerType.GuardMini:PointerType.NoActionMini:this.isAllowed()?PointerType.Guard:PointerType.NoMove,this.terminal=!0,this.targetOptional=!t,this.minimapAllowed=t,this.feedbackType=t?OrderFeedbackType.Move:OrderFeedbackType.None}isValid(){return this.sourceObject.isUnit()&&(!!this.targetOptional||!this.sourceObject.moveTrait.isDisabled())&&!(this.target&&this.game.mapShroudTrait.getPlayerShroud(this.sourceObject.owner)?.isShrouded(this.target.tile,this.target.obj?.tileElevation)&&!this.sourceObject.rules.moveToShroud)}isAllowed(){return!0}process(){let t=this.targeted?this.target.tile:void 0;const e=this.sourceObject;let i=[];return t&&i.push(new MoveTask(this.game,t,!!this.target.getBridge(),{closeEnoughTiles:this.game.rules.general.closeEnough})),e.isVehicle()&&e.harvesterTrait?i.push(new CallbackTask(()=>e.harvesterTrait.lastOreSite=void 0),e.harvesterTrait.isFull()?new ReturnOreTask(this.game,void 0,void 0,!0):new GatherOreTask(this.game,void 0,!0)):i.push(new CallbackTask(e=>{t&&![MoveResult.Success,MoveResult.CloseEnough].includes(this.sourceObject.moveTrait?.lastMoveResult)||(this.sourceObject.guardMode=!0)})),i}}class ScatterOrder extends Order{constructor(e){super(OrderType.Scatter),this.game=e,this.getPointerType=()=>PointerType.NoAction}isValid(){return(this.sourceObject.isInfantry()||this.sourceObject.isVehicle())&&this.sourceObject.rules.movementZone!==MovementZone.Fly&&!this.sourceObject.moveTrait.isDisabled()}isAllowed(){return!0}process(){if(!this.target)throw new Error("Target should be set for executing a scatter order. See OrderUnitsAction.");return[new ScatterTask(this.game,{tile:this.target.tile,toBridge:!!this.target.getBridge()})]}}class EnterTransportEvent{constructor(e){this.target=e,this.type=EventType.EnterTransport}}!function(e){e[e.MoveToQueueingTile=0]="MoveToQueueingTile",e[e.WaitForTurn=1]="WaitForTurn",e[e.MoveToTransport=2]="MoveToTransport",e[e.EnterTransport=3]="EnterTransport",e[e.ClearTransport=4]="ClearTransport"}(EnterTransportTask_State=EnterTransportTask_State||{});class EnterTransportTask extends Task{constructor(e,t){super(),this.game=e,this.target=t,this.movePerformed=!1,this.preventOpportunityFire=!1}isAllowed(e){return!this.target.isDestroyed&&!this.target.isCrashing&&this.game.areFriendly(this.target,e)&&e.zone!==ZoneType.Air&&this.target.zone!==ZoneType.Air&&this.target.transportTrait.unitFitsInside(e)&&this.target.moveTrait.moveState===MoveState.Idle&&!this.target.warpedOutTrait.isActive()&&!e.mindControllableTrait?.isActive()&&!e.mindControllerTrait?.isActive()}onStart(e){if(!this.target.transportTrait)throw new Error(`Unit ${this.target.name} is not a valid transport`);this.initialTargetTile=this.target.tile,0<this.target.transportTrait.addToLoadQueue(e)?this.state=EnterTransportTask_State.MoveToQueueingTile:this.state=EnterTransportTask_State.MoveToTransport}onEnd(e){this.target.isDestroyed||this.target.transportTrait?.removeFromLoadQueue(e)}onTick(n){if(this.isCancelling()&&this.state!==EnterTransportTask_State.EnterTransport||this.state===EnterTransportTask_State.ClearTransport||n.moveTrait.isDisabled())return!0;if(this.target.tile!==this.initialTargetTile||this.target.moveTrait.moveState!==MoveState.Idle)return!0;if(this.state===EnterTransportTask_State.MoveToQueueingTile){let r=new MovePositionHelper(this.game.map),s=this.target.onBridge?this.game.map.tileOccupation.getBridgeOnTile(this.target.tile):void 0,a;var e=new RadialTileFinder(this.game.map.tiles,this.game.map.mapBounds,this.target.tile,this.target.getFoundation(),1,1,e=>{let t=[this.game.map.tileOccupation.getBridgeOnTile(e)];t[0]&&t.push(void 0);for(var i of t)if(0<this.game.map.terrain.getPassableSpeed(e,n.rules.speedType,n.isInfantry(),!!i)&&r.isEligibleTile(e,i,s,this.target.tile))return a=i,!0;return!1}).getNextTile();return!e||(this.children.push(new MoveTask(this.game,e,!!a,{closeEnoughTiles:5})),this.children.push(new CallbackTask(()=>{[MoveResult.Success,MoveResult.CloseEnough].includes(n.moveTrait.lastMoveResult)||this.cancel()})),this.queueingNode={tile:e,onBridge:a},this.state=EnterTransportTask_State.WaitForTurn,!1)}if(this.state===EnterTransportTask_State.WaitForTurn){if(!this.target.transportTrait.unitIsFirstInLoadQueue(n))return!1;this.queueingNode=void 0,this.state=EnterTransportTask_State.MoveToTransport}if(this.state===EnterTransportTask_State.MoveToTransport){if(!this.isAllowed(n))return!0;if(!this.game.map.tileOccupation.isTileOccupiedBy(n.tile,this.target))return!!this.movePerformed||(this.children.push(new MoveInsideTask(this.game,this.target)),this.movePerformed=!0,!(this.preventOpportunityFire=!0));this.state=EnterTransportTask_State.EnterTransport}return this.state===EnterTransportTask_State.EnterTransport&&(!this.isAllowed(n)||this.isCancelling()?(this.children.push(new MoveOutsideTask(this.game,this.target)),this.state=EnterTransportTask_State.ClearTransport,!1):(this.game.limboObject(n,{selected:!1,controlGroup:this.game.getUnitSelection().getOrCreateSelectionModel(n).getControlGroupNumber(),inTransport:!0}),this.game.events.dispatch(new EnterTransportEvent(this.target)),this.game.events.dispatch(new EnterObjectEvent(this.target,n)),this.target.transportTrait.units.push(n),!0))}getTargetLinesConfig(e){return{target:this.queueingNode?void 0:this.target,pathNodes:this.queueingNode?[this.queueingNode]:[]}}}class EnterTransportOrder extends Order{constructor(e){super(OrderType.EnterTransport),this.game=e,this.targetOptional=!1,this.terminal=!0,this.feedbackType=OrderFeedbackType.Enter}getPointerType(e){return e?this.isAllowed()?PointerType.OccupyMini:PointerType.NoActionMini:this.isAllowed()?PointerType.Occupy:PointerType.NoOccupy}isValid(){return!(!this.target.obj?.isVehicle()||!this.target.obj.transportTrait||this.target.obj.isDestroyed||this.target.obj===this.sourceObject||!this.game.areFriendly(this.target.obj,this.sourceObject)||!this.sourceObject.isVehicle()&&!this.sourceObject.isInfantry())}isAllowed(){let e=this.target.obj,t=this.sourceObject;return t.zone!==ZoneType.Air&&e.zone!==ZoneType.Air&&e.transportTrait.unitFitsInside(t)&&e.moveTrait.moveState===MoveState.Idle&&!e.warpedOutTrait.isActive()&&!t.mindControllableTrait?.isActive()&&!t.mindControllerTrait?.isActive()}process(){let e=this.sourceObject,t=this.target.obj;return this.game.map.terrain.getPassableSpeed(t.tile,e.rules.speedType,e.isInfantry(),e.onBridge)?[new EnterTransportTask(this.game,t)]:[new CallbackTask(()=>{t.unitOrderTrait.addTask(new MoveTask(this.game,e.tile,e.onBridge)),t.unitOrderTrait.addTask(new CallbackTask(()=>{this.game.map.terrain.getPassableSpeed(t.tile,e.rules.speedType,e.isInfantry(),e.onBridge)&&e.unitOrderTrait.addTask(new EnterTransportTask(this.game,t))}))})]}onAdd(t,e){if(!e){let e=t.find(e=>e instanceof EnterTransportTask);if(this.isValid()&&this.isAllowed()&&e&&!e.isCancelling()&&e.target===this.target.obj)if(new RangeHelper(this.game.map.tileOccupation).isInTileRange(this.sourceObject,this.target.obj,0,Math.SQRT2))return!1}return!0}}class BuildingCaptureEvent{constructor(e){this.target=e,this.type=EventType.BuildingCapture}}class CaptureBuildingTask extends EnterBuildingTask{isAllowed(e){return e.rules.engineer&&this.target.rules.capturable&&!this.target.isDestroyed&&this.target.buildStatus!==BuildStatus.BuildDown&&!this.game.areFriendly(e,this.target)}onEnter(t){if(this.game.unspawnObject(t),this.game.gameOpts.multiEngineer){var i=this.game.rules.general;if((!this.target.rules.needsEngineer||!i.engineerAlwaysCaptureTech)&&this.target.healthTrait.health>100*i.engineerCaptureLevel){var r=Math.floor(i.engineerDamage*this.target.healthTrait.maxHitPoints),i=Math.floor((1-Math.floor(1/i.engineerDamage)*i.engineerDamage)*this.target.healthTrait.maxHitPoints);if(0<(r=Math.min(r,this.target.healthTrait.getHitPoints()-i))){i=this.game.rules.combatDamage.c4Warhead;let e=new Warhead(this.game.rules.getWarhead(i));return void e.detonate(this.game,r,this.target.tile,0,this.target.position.worldPosition,ZoneType.Ground,CollisionType.None,this.game.createTarget(this.target,this.target.tile),{player:t.owner,obj:t,weapon:void 0},SpecialWarheadType.None,void 0,0)}}}t.owner.buildingsCaptured++,this.game.changeObjectOwner(this.target,t.owner),this.game.events.dispatch(new BuildingCaptureEvent(this.target))}}class CaptureOrder extends Order{constructor(e){super(OrderType.Capture),this.game=e,this.targetOptional=!1,this.terminal=!0,this.feedbackType=OrderFeedbackType.Capture}getPointerType(e){if(!this.isAllowed())return e?PointerType.NoActionMini:PointerType.NoOccupy;if(e)return PointerType.OccupyMini;if(this.game.gameOpts.multiEngineer){var t=this.game.rules.general,e=this.target.obj;if((!e.rules.needsEngineer||!t.engineerAlwaysCaptureTech)&&e.healthTrait.health>100*t.engineerCaptureLevel)return PointerType.EngineerDamage}return PointerType.Occupy}isValid(){return!(this.target.obj?.isDestroyed||!this.target.obj?.isBuilding()||!this.sourceObject.isInfantry())&&(this.target.obj.rules.capturable&&this.sourceObject.rules.engineer&&!this.game.areFriendly(this.sourceObject,this.target.obj))}isAllowed(){return!0}process(){return[new CaptureBuildingTask(this.game,this.target.obj)]}onAdd(t,e){if(!e){let e=t.find(e=>e instanceof CaptureBuildingTask);if(this.isValid()&&this.isAllowed()&&e&&!e.isCancelling()&&e.target===this.target.obj)if(new RangeHelper(this.game.map.tileOccupation).isInTileRange(this.sourceObject,this.target.obj,0,Math.SQRT2))return!1}return!0}}class OrderFactory{constructor(e,t){this.game=e,this.map=t}create(e,t){switch(e){case OrderType.Deploy:return new DeployOrder(this.game,!0);case OrderType.DeploySelected:return new DeployOrder(this.game,!1);case OrderType.ForceMove:return new MoveOrder(this.game,this.map,t,!0);case OrderType.Move:return new MoveOrder(this.game,this.map,t);case OrderType.ForceAttack:return new AttackOrder(this.game,{forceAttack:!0});case OrderType.Attack:return new AttackOrder(this.game,{noIvanBomb:!0});case OrderType.PlaceBomb:return new AttackOrder(this.game);case OrderType.AttackMove:return new AttackMoveOrder(this.game,this.map);case OrderType.Capture:return new CaptureOrder(this.game);case OrderType.Occupy:return new OccupyOrder(this.game);case OrderType.Stop:return new StopOrder(this.game);case OrderType.Cheer:return new CheerOrder;case OrderType.Dock:return new DockOrder(this.game);case OrderType.Gather:return new GatherOrder(this.game);case OrderType.Repair:return new RepairOrder(this.game);case OrderType.Guard:return new GuardAreaOrder(this.game,!1);case OrderType.GuardArea:return new GuardAreaOrder(this.game,!0);case OrderType.Scatter:return new ScatterOrder(this.game);case OrderType.EnterTransport:return new EnterTransportOrder(this.game);default:throw new Error("Unhandled order type "+OrderType[e])}}}class OrderUnitsActionFactory{constructor(e,t,i){this.game=e,this.map=t,this.orderActionContext=i}create(){return new OrderUnitsAction(this.game,this.map,this.orderActionContext,new OrderFactory(this.game,this.map))}}!function(e){e[e.Add=0]="Add",e[e.Cancel=1]="Cancel",e[e.Pause=2]="Pause",e[e.Resume=3]="Resume",e[e.AddNext=4]="AddNext"}(UpdateType=UpdateType||{});class UpdateQueueAction extends Action{constructor(e){super(ActionType.UpdateQueue),this.game=e}unserialize(e){let t=new DataStream(e);var i;this.queueType=t.readUint8(),this.updateType=t.readUint8(),this.updateType!==UpdateType.Add&&this.updateType!==UpdateType.Cancel&&this.updateType!==UpdateType.AddNext||(i=t.readUint32(),e=t.readUint8(),this.item=this.game.rules.getTechnoByInternalId(i,e),this.quantity=t.readUint16())}serialize(){let e=new DataStream(9);if(e.dynamicSize=!1,e.writeUint8(this.queueType),e.writeUint8(this.updateType),this.updateType===UpdateType.Add||this.updateType===UpdateType.Cancel||this.updateType===UpdateType.AddNext){if(void 0===this.quantity)throw new Error("Missing quantity");if(65535<this.quantity)throw new Error("Maximum quantity exceeded");e.writeUint32(this.item.index),e.writeUint8(this.item.type),e.writeUint16(this.quantity)}return new Uint8Array(e.buffer,e.byteOffset,e.position)}print(){return this.updateType===UpdateType.Resume?"Resume queue "+QueueType[this.queueType]:this.updateType===UpdateType.Add?`Add to queue ${this.item.name} x `+this.quantity:this.updateType===UpdateType.AddNext?`Add next in queue ${this.item.name} x `+this.quantity:this.updateType===UpdateType.Pause?`Put queue ${QueueType[this.queueType]} on hold.`:this.updateType===UpdateType.Cancel?`Cancel ${this.item.name} x `+this.quantity:"Unhandled queue update type "+this.updateType}process(){let i=this.player,r=this.item,s=i.production.getQueue(this.queueType);if(this.updateType===UpdateType.Resume)s.status===QueueStatus.OnHold&&(s.status=QueueStatus.Active);else if(this.updateType===UpdateType.Add||this.updateType===UpdateType.AddNext){let e=s.find(r);if(s.status===QueueStatus.Active||s.status===QueueStatus.Idle||s.status===QueueStatus.OnHold&&e[0]!==s.getFirst()||s.status===QueueStatus.Ready&&r.type!==ObjectType.Building){let t;var a=e.reduce((e,t)=>e+t.quantity,0);if(Number.isFinite(r.buildLimit)){let e;e=0<=r.buildLimit?i.getOwnedObjectsByType(r.type,!0).filter(e=>e.name===r.name).length:i.getLimitedUnitsBuilt(r.name),t=Math.max(0,Math.abs(r.buildLimit)-(e+a))}else t=Number.POSITIVE_INFINITY;t&&i.production.isAvailableForProduction(r)&&(n=Math.min(s.maxSize-s.currentSize,s.maxItemQuantity-a,t),0<(o=Math.min(this.quantity,n))&&(this.updateType===UpdateType.AddNext?s.insertAfterFirst(r,o,r.cost):s.push(r,o,r.cost)))}}else if(this.updateType===UpdateType.Cancel){if([QueueStatus.Ready,QueueStatus.OnHold,QueueStatus.Active].includes(s.status)){let e=s.find(r);var n,o;e.length&&(n=e.reduce((e,t)=>e+t.quantity,0),0<(o=Math.min(n,this.quantity))&&(s.pop(r,o),o===n&&(i.credits+=e[0].creditsSpent)))}}else this.updateType===UpdateType.Pause&&s.status===QueueStatus.Active&&(s.status=QueueStatus.OnHold)}}class UpdateQueueActionFactory{constructor(e){this.game=e}create(){return new UpdateQueueAction(this.game)}}class PlayerDroppedEvent{constructor(e,t){this.target=e,this.assetsRedistributed=t,this.type=EventType.PlayerDropped}}class DropPlayerAction extends Action{constructor(e,t){super(ActionType.DropPlayer),this.game=e,this.localPlayerName=t}process(){if(this.localPlayerName!==this.player.name){let e=this.player;var t;e.defeated||(t=this.game.redistributeAllPlayerAssets(e),this.game.removeAllPlayerAssets(e),e.dropped=!0,this.game.events.dispatch(new PlayerDroppedEvent(e,t)))}}}class DropPlayerActionFactory{constructor(e,t){this.game=e,this.localPlayerName=t}create(){return new DropPlayerAction(this.game,this.localPlayerName)}}class BuildingRepairStartEvent{constructor(e){this.target=e,this.type=EventType.BuildingRepairStart}}class ToggleRepairAction extends Action{constructor(e){super(ActionType.ToggleRepair),this.game=e}unserialize(e){this.buildingId=new DataStream(e).readUint32()}serialize(){return new DataStream(4).writeUint32(this.buildingId).toUint8Array()}print(){return"Toggle repair "+this.buildingId}process(){var e=this.player;if(this.game.getWorld().hasObjectId(this.buildingId)){let t=this.game.getObjectById(this.buildingId);if(t.isBuilding()&&e===t.owner&&!t.isDestroyed&&t.rules.repairable&&t.rules.clickRepairable&&100!==t.healthTrait.health){let e=t.traits.get(AutoRepairTrait);e.setDisabled(!e.isDisabled()),e.isDisabled()||this.game.events.dispatch(new BuildingRepairStartEvent(t))}}}}class ToggleRepairActionFactory{constructor(e){this.game=e}create(){return new ToggleRepairAction(this.game)}}class ToggleAllianceAction extends Action{constructor(e){super(ActionType.ToggleAlliance),this.game=e}unserialize(e){this.toPlayer=this.game.getPlayer(e[0]),this.toggle=Boolean(e[1])}serialize(){return new Uint8Array([this.game.getPlayerNumber(this.toPlayer),this.toggle?1:0])}print(){return`Toggle alliance ${this.toggle?"on":"off"} with `+this.toPlayer.name}process(){var e=this.game.rules.mpDialogSettings;if(e.alliesAllowed&&e.allyChangeAllowed){var a,n=this.player,t=this.toPlayer,e=this.toggle;let i=n,r=t,s=this.game.alliances;if(!n.defeated&&s.canRequestAlliance(r)){let t=s.findByPlayers(i,r);t?t.status===AllianceStatus.Formed?e||(s.breakAlliance(i,r),this.game.onAllianceChange(t,i,!1)):t.status===AllianceStatus.Requested&&(t.players.first===r?e&&s.canFormAlliance(i,r)&&(s.acceptRequest(r,i),this.game.onAllianceChange(t,i,!0),1!==(n=this.game.getCombatants().filter(e=>e!==i&&!s.areAllied(i,e))).length||(a=s.findByPlayers(n[0],i))&&s.cancelRequest(a.players.first,a.players.second),1!==(a=this.game.getCombatants().filter(e=>e!==r&&!s.areAllied(r,e))).length||(a=s.findByPlayers(a[0],r))&&s.cancelRequest(a.players.first,a.players.second)):e||(s.cancelRequest(i,r),this.game.events.dispatch(new AllianceChangeEvent(t,AllianceEventType.Broken,i)),this.game.traits.filter(NotifyAllianceChange).forEach(e=>{e[NotifyAllianceChange.onChange](t,!1,this.game)}))):e&&s.canFormAlliance(i,r)&&((e=s.request(i,r))&&this.game.events.dispatch(new AllianceChangeEvent(e,AllianceEventType.Requested,i)))}}}}class ToggleAllianceActionFactory{constructor(e){this.game=e}create(){return new ToggleAllianceAction(this.game)}}class ActivateSuperWeaponAction extends Action{constructor(e){super(ActionType.ActivateSuperWeapon),this.game=e}unserialize(e){let t=new DataStream(e);this.superWeaponType=t.readUint8();e=t.readUint8();this.tile={x:t.readUint16(),y:t.readUint16()},this.tile2=2<e?{x:t.readUint16(),y:t.readUint16()}:void 0}serialize(){let e=new DataStream(6+(this.tile2?4:0));return e.dynamicSize=!1,e.writeUint8(this.superWeaponType),e.writeUint8(this.tile2?4:2),e.writeUint16(this.tile.x),e.writeUint16(this.tile.y),this.tile2&&(e.writeUint16(this.tile2.x),e.writeUint16(this.tile2.y)),e.toUint8Array()}print(){return`Activate SuperW ${SuperWeaponType[this.superWeaponType]} at tile (${this.tile.x}, ${this.tile.y})`+(this.tile2?`, (${this.tile2.x}, ${this.tile2.y})`:"")}process(){var e,t=this.player,i=this.game.map.tiles.getByMapCoords(this.tile.x,this.tile.y);i?(e=this.tile2?this.game.map.tiles.getByMapCoords(this.tile2.x,this.tile2.y):void 0,this.game.traits.get(SuperWeaponsTrait).activateSuperWeapon(this.superWeaponType,t,this.game,i,e)):console.warn(`Tile ${this.tile.x},${this.tile.y} doesn't exist`)}}class ActivateSuperWeaponActionFactory{constructor(e){this.game=e}create(){return new ActivateSuperWeaponAction(this.game)}}class PingLocationEvent{constructor(e,t){this.tile=e,this.player=t,this.type=EventType.PingLocation}}class PingLocationAction extends Action{constructor(e){super(ActionType.PingLocation),this.game=e}unserialize(e){let t=new DataStream(e);this.tile={x:t.readUint16(),y:t.readUint16()}}serialize(){let e=new DataStream(4);return e.writeUint16(this.tile.x),e.writeUint16(this.tile.y),e.toUint8Array()}print(){return`Ping location at tile (${this.tile.x}, ${this.tile.y})`}process(){var e=this.player,t=this.game.map.tiles.getByMapCoords(this.tile.x,this.tile.y);if(t){this.game.events.dispatch(new PingLocationEvent(t,e));for(var i of[e,...this.game.alliances.getAllies(e)])this.game.events.dispatch(new RadarEvent(i,RadarEventType.GenericNonCombat,t))}else console.warn(`Tile ${this.tile.x},${this.tile.y} doesn't exist`)}}class PingLocationActionFactory{constructor(e){this.game=e}create(){return new PingLocationAction(this.game)}}class PlayerResignedEvent{constructor(e,t){this.target=e,this.assetsRedistributed=t,this.type=EventType.PlayerResigned}}class ObserveGameAction extends Action{constructor(e){super(ActionType.ObserveGame),this.game=e}process(){let e=this.player;var t;this.game.removeAllPlayerAssets(e),!e.isCombatant()||e.defeated||e.isObserver||(e.resigned=!0,e.defeated=!0,e.isObserver=!0,this.game.events.dispatch(new PlayerResignedEvent(e)),this.game.events.dispatch(new PlayerDefeatedEvent(e)),this.game.mapShroudTrait.getPlayerShroud(e)?.revealAll(),t=e.radarTrait.isDisabled(),e.radarTrait.setDisabled(!1),t&&this.game.events.dispatch(new RadarOnOffEvent(e,!0)))}}class ObserveGameActionFactory{constructor(e){this.game=e}create(){return new ObserveGameAction(this.game)}}class ResignGameAction extends Action{constructor(e,t){super(ActionType.ResignGame),this.game=e,this.localPlayerName=t}process(){if(this.localPlayerName!==this.player.name){let e=this.player;var t=this.game.redistributeAllPlayerAssets(e);this.game.removeAllPlayerAssets(e),e.isCombatant()&&(e.resigned=!0,this.game.events.dispatch(new PlayerResignedEvent(e,t)))}}}class ResignGameActionFactory{constructor(e,t){this.game=e,this.localPlayerName=t}create(){return new ResignGameAction(this.game,this.localPlayerName)}}!function(e){e[e.SetGlobalDebugText=0]="SetGlobalDebugText",e[e.SetUnitDebugText=1]="SetUnitDebugText"}(DebugCommandType=DebugCommandType||{});class DebugCommand{constructor(e,t){this.type=e,this.params=t}}class DebugAction extends Action{constructor(e){super(ActionType.DebugCommand),this.game=e}unserialize(e){let t=new DataStream(e);e=t.readUint8();e===DebugCommandType.SetUnitDebugText?this.command=new DebugCommand(e,{unitId:t.readUint32(),label:t.readCString()||void 0}):e===DebugCommandType.SetGlobalDebugText?this.command=new DebugCommand(e,{text:t.readCString()}):console.warn(`Debug command ${e} not implemented`)}serialize(){let e=new DataStream;if(e.writeUint8(this.command.type),this.command.type===DebugCommandType.SetUnitDebugText){var t=this.command.params;e.writeUint32(t.unitId),e.writeCString(t.label||"")}else{if(this.command.type!==DebugCommandType.SetGlobalDebugText)throw new Error(`Debug command ${this.command.type} not implemented`);t=this.command.params;e.writeCString(t.text)}return e.toUint8Array()}process(){if(this.command.type===DebugCommandType.SetUnitDebugText){var{unitId:t,label:i}=this.command.params;if(this.game.getWorld().hasObjectId(t)){let e=this.game.getObjectById(t);e.isTechno()&&(e.debugLabel=i)}}else this.command.type===DebugCommandType.SetGlobalDebugText?(i=this.command.params["text"],this.game.debugText.value=i):console.warn(`Debug command ${this.command.type} not implemented`)}}class DebugActionFactory{constructor(e){this.game=e}create(){return new DebugAction(this.game)}}class ActionFactoryReg{register(e,t,i){var r=new OrderActionContext;e.registerFactory(ActionType.NoAction,new NoActionFactory),e.registerFactory(ActionType.PlaceBuilding,new PlaceBuildingActionFactory(t)),e.registerFactory(ActionType.SellObject,new SellObjectActionFactory(t)),e.registerFactory(ActionType.ToggleRepair,new ToggleRepairActionFactory(t)),e.registerFactory(ActionType.SelectUnits,new SelectUnitsActionFactory(t,r)),e.registerFactory(ActionType.OrderUnits,new OrderUnitsActionFactory(t,t.map,r)),e.registerFactory(ActionType.UpdateQueue,new UpdateQueueActionFactory(t)),e.registerFactory(ActionType.ToggleAlliance,new ToggleAllianceActionFactory(t)),e.registerFactory(ActionType.ActivateSuperWeapon,new ActivateSuperWeaponActionFactory(t)),e.registerFactory(ActionType.PingLocation,new PingLocationActionFactory(t)),e.registerFactory(ActionType.DropPlayer,new DropPlayerActionFactory(t,i)),e.registerFactory(ActionType.ObserveGame,new ObserveGameActionFactory(t)),e.registerFactory(ActionType.ResignGame,new ResignGameActionFactory(t,i)),e.registerFactory(ActionType.DebugCommand,new DebugActionFactory(t))}}class SharedDetectDisguiseTrait_SharedDetectDisguiseTrait{constructor(){this.detectors=new Set}[NotifySpawn_NotifySpawn.onSpawn](e,t){this.isGlobalDetector(e)&&(this.detectors.add(e),this.updateAroundDetector(e,t)),this.isDisguisable(e)&&this.detect(e,t)}[NotifyUnspawn_NotifyUnspawn.onUnspawn](e,t){e.isTechno()&&(this.isGlobalDetector(e)&&(this.detectors.delete(e),this.updateAroundDetector(e,t)),this.isDisguisable(e)&&this.undetect(e,t))}[NotifyOwnerChange_NotifyOwnerChange.onChange](e,t,i){this.isGlobalDetector(e)&&this.updateAroundDetector(e,i),this.isDisguisable(e)&&(this.undetect(e,i),this.detect(e,i))}[NotifyTileChange.onTileChange](e,t,i){this.isGlobalDetector(e)&&(this.updateAroundDetector(e,t,i),this.updateAroundDetector(e,t)),this.isDisguisable(e)&&(this.undetect(e,t),this.detect(e,t))}[NotifyPower.onPowerLow](t,e){var i=[...this.detectors].filter(e=>e.owner===t&&e.isBuilding()&&e.poweredTrait&&!e.poweredTrait.isPoweredOn());this.updateAroundDetectors(i,e)}[NotifyPower.onPowerRestore](t,e){var i=[...this.detectors].filter(e=>e.owner===t&&e.isBuilding()&&e.poweredTrait);this.updateAroundDetectors(i,e)}[NotifyPower.onPowerChange](e,t){}updateAroundDetectors(e,t){let i=new Set;for(var r of e)for(var s of this.findTechnosAroundDetector(r,t,r.tile))i.add(s);for(var a of i)this.isDisguisable(a)&&(this.undetect(a,t),this.detect(a,t))}updateAroundDetector(e,t,i=e.tile){var r;for(r of this.findTechnosAroundDetector(e,t,i))this.isDisguisable(r)&&(this.undetect(r,t),this.detect(r,t))}findTechnosAroundDetector(e,t,i){var r=e.getFoundation(),r=Math.max(r.width,r.height),e=e.rules.detectDisguiseRange+r,r=new Vector2(i.rx,i.ry).addScalar(-e),e=new Vector2(i.rx,i.ry).addScalar(e);return t.map.technosByTile.queryRange(new Box2(r,e))}detect(e,t){let i=new Set,r=new RangeHelper(t.map.tileOccupation);for(var s of this.detectors)if(!t.areFriendly(s,e)){var a=s.owner,n=s.rules.detectDisguiseRange;if(!i.has(a))if(!(s.isBuilding()&&s.poweredTrait&&!s.poweredTrait.isPoweredOn())&&r.tileDistance(e,s.tile)<=n)for(var o of[a,...t.alliances.getAllies(a)])i.add(o)}for(var l of i)l.sharedDetectDisguiseTrait?.add(e)}undetect(e,t){for(var i of t.getCombatants())i.sharedDetectDisguiseTrait?.delete(e)}isGlobalDetector(e){return!(!e.isTechno()||!e.rules.detectDisguiseRange)}isDisguisable(e){return!(!e.isInfantry()&&!e.isVehicle()||!e.disguiseTrait)}}class SharedDetectCloakTrait{constructor(){this.detectors=new Set}[NotifySpawn_NotifySpawn.onSpawn](e,t){this.isGlobalDetector(e)&&(this.detectors.add(e),this.updateAroundDetector(e,t)),this.isCloakable(e)&&this.detect(e,t)}[NotifyUnspawn_NotifyUnspawn.onUnspawn](e,t){e.isTechno()&&this.isGlobalDetector(e)&&this.detectors.delete(e)}[NotifyOwnerChange_NotifyOwnerChange.onChange](e,t,i){this.isGlobalDetector(e)&&this.updateAroundDetector(e,i),this.isCloakable(e)&&this.detect(e,i)}[NotifyTileChange.onTileChange](e,t,i){this.isGlobalDetector(e)&&this.updateAroundDetector(e,t),this.isCloakable(e)&&this.detect(e,t)}[NotifyObjectTraitAdd.onAdd](e,t,i){e.isTechno()&&(t instanceof CloakableTrait?this.isCloakable(e)&&this.detect(e,i):t instanceof SensorsTrait&&this.isGlobalDetector(e)&&this.updateAroundDetector(e,i))}[NotifyPower.onPowerLow](e,t){}[NotifyPower.onPowerRestore](t,e){var i=[...this.detectors].filter(e=>e.owner===t&&e.isBuilding()&&e.poweredTrait);this.updateAroundDetectors(i,e)}[NotifyPower.onPowerChange](e,t){}[NotifyTick.onTick](e){for(var t of e.getCombatants()){var i;for(i of t.getOwnedObjects())i.cloakableTrait&&!i.cloakableTrait.isCloaked()&&this.detect(i,e)}}updateAroundDetectors(e,t){let i=new Set;for(var r of e)for(var s of this.findTechnosAroundDetector(r,t))i.add(s);for(var a of i)this.isCloakable(a)&&this.detect(a,t)}updateAroundDetector(e,t){var i;for(i of this.findTechnosAroundDetector(e,t))this.isCloakable(i)&&this.detect(i,t)}findTechnosAroundDetector(e,t){var i=e.getFoundation(),r=Math.max(i.width,i.height),i=e.rules.sensorsSight+r,r=new Vector2(e.tile.rx,e.tile.ry).addScalar(-i),i=new Vector2(e.tile.rx,e.tile.ry).addScalar(i);return t.map.technosByTile.queryRange(new Box2(r,i))}detect(e,t){let i=new RangeHelper(t.map.tileOccupation);for(var r of this.detectors)if(!t.areFriendly(r,e)){var s=r.rules.sensorsSight;if(!(r.isBuilding()&&r.poweredTrait&&!r.poweredTrait.isPoweredOn())&&i.tileDistance(e,r.tile)<=s){s=e.cloakableTrait?.isCloaked();if(e.cloakableTrait.uncloak(t),s)for(var a of[r.owner,...t.alliances.getAllies(r.owner)])t.traits.get(RadarTrait_RadarTrait).addEventForPlayer(RadarEventType.GenericNonCombat,a,e.tile,t);break}}}isGlobalDetector(e){return!(!e.isTechno()||!e.sensorsTrait&&!e.rules.sensorArray||!e.rules.sensorsSight)}isCloakable(e){return e.isTechno()&&!!e.cloakableTrait}}class StalemateDetectEvent{constructor(){this.type=EventType.StalemateDetect}}class StalemateDetectTrait{constructor(){this.stale=!1,this.allPlayersCredits=new Map,this.resetCountdown()}isStale(){return this.stale}getCountdownTicks(){return this.countdownTicks}resetCountdown(){this.countdownTicks=Math.floor(60*StalemateDetectTrait.graceMinutes*GameSpeed.BASE_TICKS_PER_SECOND)}clearStale(){this.stale=!1,this.resetCountdown()}[NotifyTick.onTick](e){0<this.countdownTicks?this.countdownTicks--:this.stale||(this.stale=!0,this.resetCountdown(),e.events.dispatch(new StalemateDetectEvent));for(var t of e.getCombatants()){var i=this.allPlayersCredits.get(t);i!==t.credits&&(this.allPlayersCredits.set(t,t.credits),t.credits>(i??0)&&t.production.hasAnyFactory()&&this.clearStale())}}[NotifyProduceUnit.onProduce](){this.clearStale()}[NotifyPlaceBuilding.onPlace](e){e.wallTrait||this.clearStale()}[NotifyDestroy_NotifyDestroy.onDestroy](e,t,i){!e.isBuilding()||e.owner.isNeutral||e.wallTrait||e.rules.insignificant||e.owner.defeated&&this.stale||i?.obj&&t.areFriendly(e,i.obj)||this.clearStale()}[NotifyOwnerChange_NotifyOwnerChange.onChange](e,t,i){e.isBuilding()&&!t.isNeutral&&(i.alliances.areAllied(e.owner,t)||this.clearStale())}}StalemateDetectTrait.graceMinutes=10;class GameOptSanitizer{static sanitize(e,t){t=t.mpDialogSettings;e.credits=Math.floor(clamp(e.credits,t.minMoney,t.maxMoney)),e.gameSpeed=Math.floor(clamp(e.gameSpeed,0,6)),e.unitCount=Math.floor(clamp(e.unitCount,t.minUnitCount,t.maxUnitCount))}}class GameOptRandomGen{static factory(e,t){return new this(Prng.factory(e,t))}constructor(e){this.prng=e}generateColors(e){let t=[...e.humanPlayers,...e.aiPlayers].filter(isNotNullOrUndefined),i=t.map(e=>e.colorId).filter(e=>e!==RANDOM_COLOR_ID);e=mpAllowedColors.length;let r=new Array(e).fill(0).map((e,t)=>t).filter(e=>!i.includes(e)),s=new Map;return t.forEach(e=>{if(e.countryId!==OBS_COUNTRY_ID&&e.colorId===RANDOM_COLOR_ID){if(r.length<1)throw new Error("Out of available colors to choose from");var t=this.prng.generateRandomInt(0,r.length-1);s.set(e,r[t]),r.splice(t,1)}}),s}generateCountries(e,t){let i=t.getMultiplayerCountries().length,r=[...e.humanPlayers,...e.aiPlayers].filter(isNotNullOrUndefined),s=new Map;return r.forEach(e=>{e.countryId===RANDOM_COUNTRY_ID&&s.set(e,this.prng.generateRandomInt(0,i-1))}),s}generateStartLocations(i,r){let e=[...i.humanPlayers,...i.aiPlayers].filter(isNotNullOrUndefined),t=e.filter(e=>e.startPos!==RANDOM_START_POS).map(e=>e.startPos),s=[...r.keys()].filter(e=>!t.includes(e)),a=[];for(;s.length;){var n=s.length?this.prng.generateRandomInt(0,s.length-1):0;a.push(...s.splice(n,1))}if(a.unshift(...t),3<=a.length)for(var o of[1,2])if(!(t.length-1>=o)){let e=a.map(e=>r[e]),t=this.findFarthestPointFrom(e.slice(0,o),e.slice(o));var l=e.findIndex(e=>e.x===t.x&&e.y===t.y);a.splice(o,0,...a.splice(l,1))}if(4<=a.length)if(t.length-1<3){let e=a.map(e=>r[e]),t=this.findFarthestPointFrom(e.slice(2,3),e.slice(3));i=e.findIndex(e=>e.x===t.x&&e.y===t.y);a.splice(3,0,...a.splice(i,1))}a.splice(0,t.length);let h=new Map,c=-1;return e.forEach(e=>{if(e.countryId!==OBS_COUNTRY_ID&&e.startPos===RANDOM_START_POS){if(c>=a.length-1)throw new RangeError("Map has fewer starting locations than players");h.set(e,a[++c])}}),h}findFarthestPointFrom(e,t){let r=e.map(e=>new Vector2(e.x,e.y)),s,a=0;if(!t.length)throw new Error("Search array must have at least one element");for(var n of t){let i=new Vector2(n.x,n.y);var o=r.reduce((e,t)=>e+i.distanceTo(t),0);o>=a&&(s=n,a=o)}return s}}class MapLightingTrait{get onChange(){return this._onChange.asEvent()}constructor(e,t){this.mapLighting=new MapLighting,this._onChange=new EventDispatcher,this.ambientChangeRate=e.ambientChangeRate,this.ambientChangeStep=e.ambientChangeStep,t&&this.mapLighting.copy(t)}setAmbientChangeRate(e){this.ambientChangeRate=e}setAmbientChangeStep(e){this.ambientChangeStep=e}setTargetAmbientIntensity(e){this.targetAmbient=e}getAmbient(){return this.mapLighting}[NotifyTick.onTick](){var e;void 0!==this.targetAmbient&&(this.ambientUpdateTicks??(this.ambientUpdateTicks=Math.floor(60*GameSpeed.BASE_TICKS_PER_SECOND*this.ambientChangeRate)),this.ambientUpdateTicks<=0?(this.ambientUpdateTicks=void 0,e=this.mapLighting.ambient,(e=this.targetAmbient-e)?(e=Math.sign(e)*Math.min(this.ambientChangeStep,Math.abs(e)),this.mapLighting.ambient+=e,this._onChange.dispatch(this,this.mapLighting)):this.targetAmbient=void 0):this.ambientUpdateTicks--)}}class Ai{constructor(e){this.ini=e}getIni(){return this.ini}}var _Bot_debugMode,BotState,__classPrivateFieldGet=function(e,t,i,r){if("a"===i&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?r:"a"===i?r.call(e):r?r.value:t.get(e)},__classPrivateFieldSet=function(e,t,i,r,s){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!s)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!s:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?s.call(e,i):s?s.value=i:t.set(e,i),i};class Bot{get game(){return this.context?.game}get player(){return this.context?.player}get gameApi(){return this.context?.game}get actionsApi(){return this.context?.player.actions}get productionApi(){return this.context?.player.production}get logger(){return this.context?.logger}constructor(e,t){this.name=e,this.country=t,_Bot_debugMode.set(this,!1)}setContext(e){this.context=e,this.context.logger.setDebugLevel(__classPrivateFieldGet(this,_Bot_debugMode,"f"))}setGameApi(e){}setActionsApi(e){}setProductionApi(e){}setLogger(e){}setDebugMode(e){return __classPrivateFieldSet(this,_Bot_debugMode,e,"f"),this.context?.logger.setDebugLevel(e),this}getDebugMode(){return __classPrivateFieldGet(this,_Bot_debugMode,"f")}onGameInit(e){}onGameStart(e){}onGameTick(e){}onGameEvent(e,t){}}_Bot_debugMode=new WeakMap,function(e){e[e.Initial=0]="Initial",e[e.Deployed=1]="Deployed",e[e.Attacking=2]="Attacking",e[e.Defeated=3]="Defeated"}(BotState=BotState||{});class DummyBot extends Bot{constructor(){super(...arguments),this.botState=BotState.Initial}onGameStart(t){var e=t.getTickRate();this.tickRatio=Math.ceil(e/5),this.enemyPlayers=t.getPlayers().filter(e=>e!==this.name&&!t.areAlliedPlayers(this.name,e))}onGameTick(e){if(e.getCurrentTick()%this.tickRatio==0)switch(this.botState){case BotState.Initial:{const i=e.getGeneralRules().baseUnit;if(e.getVisibleUnits(this.name,"self",e=>e.constructionYard).length){this.botState=BotState.Deployed;break}var t=e.getVisibleUnits(this.name,"self",e=>i.includes(e.name));t.length&&this.actionsApi.orderUnits([t[0]],OrderType.DeploySelected);break}case BotState.Deployed:break;case BotState.Attacking:e.getVisibleUnits(this.name,"self",e=>e.isSelectableCombatant).length||(this.botState=BotState.Defeated,this.actionsApi.quitGame())}}}class BotFactory{constructor(e){this.botsLib=e}create(e){if(!e.isAi)throw new Error(`Player "${e.name}" is not an AI`);switch(e.aiDifficulty){case AiDifficulty.Easy:return new DummyBot(e.name,e.country.name);case AiDifficulty.Medium:if(this.botsLib.SupalosaBot)return new this.botsLib.SupalosaBot(e.name,e.country.name);default:throw new Error(`Unsupported AI difficulty "${e.aiDifficulty}"`)}}}class ActionQueue{constructor(){this.actions=[]}push(...e){this.actions.push(...e)}getLast(){return this.actions[this.actions.length-1]}dequeueAll(){var e=[...this.actions];return this.actions.length=0,e}dequeueLast(){return this.actions.pop()}clear(){this.actions.length=0}}var ActionsApi_classPrivateFieldSet=function(e,t,i,r,s){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!s)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!s:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?s.call(e,i):s?s.value=i:t.set(e,i),i},ActionsApi_classPrivateFieldGet=function(e,t,i,r){if("a"===i&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?r:"a"===i?r.call(e):r?r.value:t.get(e)};class ActionsApi{constructor(e,t,i,r,s){_ActionsApi_instances.add(this),_ActionsApi_actionFactory.set(this,void 0),_ActionsApi_actionQueue.set(this,void 0),_ActionsApi_game.set(this,void 0),_ActionsApi_bot.set(this,void 0),_ActionsApi_chatApi.set(this,void 0),ActionsApi_classPrivateFieldSet(this,_ActionsApi_actionFactory,t,"f"),ActionsApi_classPrivateFieldSet(this,_ActionsApi_actionQueue,i,"f"),ActionsApi_classPrivateFieldSet(this,_ActionsApi_game,e,"f"),ActionsApi_classPrivateFieldSet(this,_ActionsApi_bot,r,"f"),ActionsApi_classPrivateFieldSet(this,_ActionsApi_chatApi,s,"f")}placeBuilding(t,i,r){ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.PlaceBuilding,e=>{e.buildingRules=ActionsApi_classPrivateFieldGet(this,_ActionsApi_game,"f").rules.getBuilding(t),e.tile={x:i,y:r}})}sellObject(t){ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.SellObject,e=>{e.objectId=t})}sellBuilding(e){this.sellObject(e)}toggleRepairWrench(t){ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.ToggleRepair,e=>{e.buildingId=t})}toggleAlliance(t,i){ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.ToggleAlliance,e=>{e.toPlayer=ActionsApi_classPrivateFieldGet(this,_ActionsApi_game,"f").getPlayerByName(t),e.toggle=i})}pauseProduction(t){ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.UpdateQueue,e=>{e.queueType=t,e.updateType=UpdateType.Pause})}resumeProduction(t){ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.UpdateQueue,e=>{e.queueType=t,e.updateType=UpdateType.Resume})}queueForProduction(t,e,i,r){let s=ActionsApi_classPrivateFieldGet(this,_ActionsApi_game,"f").rules.getObject(e,i);ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.UpdateQueue,e=>{e.queueType=t,e.updateType=UpdateType.Add,e.item=s,e.quantity=r})}unqueueFromProduction(t,e,i,r){let s=ActionsApi_classPrivateFieldGet(this,_ActionsApi_game,"f").rules.getObject(e,i);ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.UpdateQueue,e=>{e.queueType=t,e.updateType=UpdateType.Cancel,e.item=s,e.quantity=r})}activateSuperWeapon(t,i,r){ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.ActivateSuperWeapon,e=>{e.superWeaponType=t,e.tile={x:i.rx,y:i.ry},e.tile2=r?{x:r.rx,y:r.ry}:void 0})}orderUnits(t,i,r,s,a){ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.SelectUnits,e=>{e.unitIds=t});let n;if(r){let e,t;if(s){e=void 0;var o=ActionsApi_classPrivateFieldGet(this,_ActionsApi_game,"f").map.tiles.getByMapCoords(r,s);if(!o)throw new Error(`No tile found at rx,ry=${r},`+s);t=o,a&&(e=ActionsApi_classPrivateFieldGet(this,_ActionsApi_game,"f").map.tileOccupation.getBridgeOnTile(o))}else{if(!ActionsApi_classPrivateFieldGet(this,_ActionsApi_game,"f").getWorld().hasObjectId(r))return;e=ActionsApi_classPrivateFieldGet(this,_ActionsApi_game,"f").getObjectById(r),t=e.tile}n=ActionsApi_classPrivateFieldGet(this,_ActionsApi_game,"f").createTarget(e,t)}ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.OrderUnits,e=>{e.orderType=i,e.target=n})}sayAll(e){ActionsApi_classPrivateFieldGet(this,_ActionsApi_chatApi,"f")?.sayAll(ActionsApi_classPrivateFieldGet(this,_ActionsApi_bot,"f").name,e)}setGlobalDebugText(t){ActionsApi_classPrivateFieldGet(this,_ActionsApi_bot,"f").getDebugMode()&&ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.DebugCommand,e=>{e.command=new DebugCommand(DebugCommandType.SetGlobalDebugText,{text:t||""})})}setUnitDebugText(t,i){ActionsApi_classPrivateFieldGet(this,_ActionsApi_bot,"f").getDebugMode()&&ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.DebugCommand,e=>{e.command=new DebugCommand(DebugCommandType.SetUnitDebugText,{unitId:t,label:i})})}quitGame(){ActionsApi_classPrivateFieldGet(this,_ActionsApi_instances,"m",_ActionsApi_pushAction).call(this,ActionType.ResignGame)}}var ApiEventType,_ActionsApi_actionFactory=new WeakMap,_ActionsApi_actionQueue=new WeakMap,_ActionsApi_game=new WeakMap,_ActionsApi_bot=new WeakMap,_ActionsApi_chatApi=new WeakMap,_ActionsApi_instances=new WeakSet,_ActionsApi_pushAction=function(e,t){let i=ActionsApi_classPrivateFieldGet(this,_ActionsApi_actionFactory,"f").create(e);i.player=ActionsApi_classPrivateFieldGet(this,_ActionsApi_game,"f").getPlayerByName(ActionsApi_classPrivateFieldGet(this,_ActionsApi_bot,"f").name),t?.(i),ActionsApi_classPrivateFieldGet(this,_ActionsApi_actionQueue,"f").push(i)},EventsApi_classPrivateFieldSet=function(e,t,i,r,s){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!s)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!s:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?s.call(e,i):s?s.value=i:t.set(e,i),i},EventsApi_classPrivateFieldGet=function(e,t,i,r){if("a"===i&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?r:"a"===i?r.call(e):r?r.value:t.get(e)};!function(e){e[e.ObjectOwnerChange=0]="ObjectOwnerChange",e[e.ObjectSpawn=1]="ObjectSpawn",e[e.ObjectUnspawn=2]="ObjectUnspawn",e[e.ObjectDestroy=3]="ObjectDestroy"}(ApiEventType=ApiEventType||{});class EventsApi{constructor(e){_EventsApi_instances.add(this),_EventsApi_eventBus.set(this,void 0),_EventsApi_listenerDisposers.set(this,[]),EventsApi_classPrivateFieldSet(this,_EventsApi_eventBus,e,"f")}subscribe(e,t){let i=void 0,r;r="function"==typeof e?e:(i=e,t);t=EventsApi_classPrivateFieldGet(this,_EventsApi_eventBus,"f").subscribe(e=>{e=EventsApi_classPrivateFieldGet(this,_EventsApi_instances,"m",_EventsApi_translateGameEvent).call(this,e);!e||void 0!==i&&i!==e.type||r(e)});return EventsApi_classPrivateFieldGet(this,_EventsApi_listenerDisposers,"f").push(t),t}dispose(){for(var e of EventsApi_classPrivateFieldGet(this,_EventsApi_listenerDisposers,"f"))e();EventsApi_classPrivateFieldGet(this,_EventsApi_listenerDisposers,"f").length=0}}var _EventsApi_eventBus=new WeakMap,_EventsApi_listenerDisposers=new WeakMap,_EventsApi_instances=new WeakSet,_EventsApi_translateGameEvent=function(t){switch(t.type){case EventType.ObjectOwnerChange:return{type:ApiEventType.ObjectOwnerChange,prevOwnerName:t.prevOwner.name,newOwnerName:t.target.owner.name,target:t.target.id};case EventType.ObjectSpawn:return{type:ApiEventType.ObjectSpawn,target:t.gameObject.id};case EventType.ObjectUnspawn:return{type:ApiEventType.ObjectUnspawn,target:t.gameObject.id};case EventType.ObjectDestroy:{let e=t;return e.target.isProjectile()?void 0:{type:ApiEventType.ObjectDestroy,target:e.target.id,attackerInfo:e.attackerInfo?{playerName:e.attackerInfo.player.name,objId:e.attackerInfo.obj?.id,weaponName:e.attackerInfo.weapon?.rules.name}:void 0}}default:return}},MapApi_classPrivateFieldSet=function(e,t,i,r,s){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!s)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!s:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?s.call(e,i):s?s.value=i:t.set(e,i),i},MapApi_classPrivateFieldGet=function(e,t,i,r){if("a"===i&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?r:"a"===i?r.call(e):r?r.value:t.get(e)};class MapApi{constructor(e){_MapApi_instances.add(this),_MapApi_game.set(this,void 0),_MapApi_map.set(this,void 0),MapApi_classPrivateFieldSet(this,_MapApi_game,e,"f"),MapApi_classPrivateFieldSet(this,_MapApi_map,e.map,"f")}getRealMapSize(){return MapApi_classPrivateFieldGet(this,_MapApi_map,"f").tiles.getMapSize()}getStartingLocations(){return MapApi_classPrivateFieldGet(this,_MapApi_map,"f").startingLocations.map(e=>new Vector2(e.x,e.y))}getTheaterType(){return MapApi_classPrivateFieldGet(this,_MapApi_map,"f").getTheaterType()}getTile(e,t){t=MapApi_classPrivateFieldGet(this,_MapApi_map,"f").tiles.getByMapCoords(e,t);if(t&&MapApi_classPrivateFieldGet(this,_MapApi_map,"f").mapBounds.isWithinBounds(t))return t}getTilesInRect(e,t){let i=t?MapApi_classPrivateFieldGet(this,_MapApi_map,"f").tiles.getInRectangle(e,t):MapApi_classPrivateFieldGet(this,_MapApi_map,"f").tiles.getInRectangle(e);return i.filter(e=>MapApi_classPrivateFieldGet(this,_MapApi_map,"f").mapBounds.isWithinBounds(e))}getObjectsOnTile(e){return MapApi_classPrivateFieldGet(this,_MapApi_map,"f").getObjectsOnTile(e).map(e=>e.id)}hasBridgeOnTile(e){return!!e.onBridgeLandType}hasHighBridgeOnTile(e){return!!MapApi_classPrivateFieldGet(this,_MapApi_map,"f").tileOccupation.getBridgeOnTile(e)?.isHighBridge()}isPassableTile(e,t,i,r){return r=r??t===SpeedType.Foot,0<MapApi_classPrivateFieldGet(this,_MapApi_map,"f").terrain.getPassableSpeed(e,t,r,i)}findPath(e,t,i,r,s){let a=MapApi_classPrivateFieldGet(this,_MapApi_game,"f").map.terrain.computePath(e,t,i.tile,i.onBridge,r.tile,r.onBridge,{bestEffort:s?.bestEffort,excludeTiles:s?.excludeNodes?e=>s.excludeNodes({tile:e.tile,onBridge:!!e.onBridge}):void 0,maxExpandedNodes:s?.maxExpandedNodes});return a.map(e=>({tile:e.tile,onBridge:!!e.onBridge}))}getReachabilityMap(e,t){let i=MapApi_classPrivateFieldGet(this,_MapApi_game,"f").map.terrain.getIslandIdMap(e,t);return{isReachable(e,t){e=this.getRegionId(e),t=this.getRegionId(t);return void 0!==e&&e===t},getRegionId(e){return i.get(e.tile,e.onBridge)}}}isVisibleTile(e,t,i=0){var r=MapApi_classPrivateFieldGet(this,_MapApi_game,"f").getPlayerByName(t);if(!r)throw new Error(`Player "${t}" doesn't exist`);return!MapApi_classPrivateFieldGet(this,_MapApi_game,"f").mapShroudTrait.getPlayerShroud(r)?.isShrouded(e,i)}getTileResourceData(e){e=MapApi_classPrivateFieldGet(this,_MapApi_map,"f").getObjectsOnTile(e).find(e=>e.isOverlay()&&e.isTiberium()||e.isTerrain()&&e.rules.spawnsTiberium);return e?MapApi_classPrivateFieldGet(this,_MapApi_instances,"m",_MapApi_getTileResourceDataFromObject).call(this,e):void 0}getAllTilesResourceData(){var e;let t=[];for(e of MapApi_classPrivateFieldGet(this,_MapApi_game,"f").getWorld().getAllObjects()){var i=MapApi_classPrivateFieldGet(this,_MapApi_instances,"m",_MapApi_getTileResourceDataFromObject).call(this,e);i&&t.push(i)}return t}}var _MapApi_game=new WeakMap,_MapApi_map=new WeakMap,_MapApi_instances=new WeakSet,_MapApi_getTileResourceDataFromObject=function(t){let i;if(t.isOverlay()&&t.isTiberium()){let e=t.traits.get(TiberiumTrait);var r=e.getTiberiumType(),s=e.getBailCount();i={tile:t.tile,ore:r!==TiberiumType.Gems?s:0,gems:r===TiberiumType.Gems?s:0,spawnsOre:!1}}else t.isTerrain()&&t.rules.spawnsTiberium&&(i={tile:t.tile,ore:0,gems:0,spawnsOre:!0});return i},RulesApi_classPrivateFieldGet=function(e,t,i,r){if("a"===i&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?r:"a"===i?r.call(e):r?r.value:t.get(e)},RulesApi_classPrivateFieldSet=function(e,t,i,r,s){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!s)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!s:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?s.call(e,i):s?s.value=i:t.set(e,i),i};class RulesApi{get allObjectRules(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").allObjectRules}get buildingRules(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").buildingRules}get infantryRules(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").infantryRules}get vehicleRules(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").vehicleRules}get aircraftRules(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").aircraftRules}get terrainRules(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").terrainRules}get overlayRules(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").overlayRules}get countryRules(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").countryRules}get general(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").general}get ai(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").ai}get crateRules(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").crateRules}get combatDamage(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").combatDamage}get radiation(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").radiation}constructor(e){_RulesApi_rules.set(this,void 0),RulesApi_classPrivateFieldSet(this,_RulesApi_rules,e,"f")}hasObject(e,t){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").hasObject(e,t)}getObject(e,t){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").getObject(e,t)}getBuilding(e){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").getBuilding(e)}getWeapon(e){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").getWeapon(e)}getWarhead(e){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").getWarhead(e)}getProjectile(e){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").getProjectile(e)}getOverlayName(e){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").getOverlayName(e)}getOverlayId(e){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").getOverlayId(e)}getOverlay(e){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").getOverlay(e)}getCountry(e){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").getCountry(e)}getMultiplayerCountries(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").getMultiplayerCountries()}getIni(){return RulesApi_classPrivateFieldGet(this,_RulesApi_rules,"f").getIni()}}var _RulesApi_rules=new WeakMap,GameApi_classPrivateFieldSet=function(e,t,i,r,s){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!s)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!s:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?s.call(e,i):s?s.value=i:t.set(e,i),i},GameApi_classPrivateFieldGet=function(e,t,i,r){if("a"===i&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?r:"a"===i?r.call(e):r?r.value:t.get(e)};class GameApi{get mapApi(){return this.map}get rulesApi(){return this.rules}constructor(e,t){_GameApi_instances.add(this),_GameApi_game.set(this,void 0),_GameApi_useInternalRng.set(this,void 0),GameApi_classPrivateFieldSet(this,_GameApi_game,e,"f"),GameApi_classPrivateFieldSet(this,_GameApi_useInternalRng,t,"f"),this.map=new MapApi(e),this.rules=new RulesApi(e.rules)}isPlayerDefeated(e){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getPlayerByName(e).defeated}areAlliedPlayers(e,t){var i=GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getPlayerByName(e);if(!i)throw new Error(`Player "${e}" doesn't exist`);e=GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getPlayerByName(t);if(!e)throw new Error(`Player "${t}" doesn't exist`);return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").alliances.areAllied(i,e)}canPlaceBuilding(e,t,i,r){var s=GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getPlayerByName(e);if(!s)throw new Error(`Player "${e}" doesn't exist`);return(r=r??{}).ignoreAdjacent??(r.ignoreAdjacent=this.rules.getBuilding(t).constructionYard),GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getConstructionWorker(s).canPlaceAt(t,i,{normalizedTile:!0,...r})}getBuildingPlacementData(e){e=GameApi_classPrivateFieldGet(this,_GameApi_game,"f").art.getObject(e,ObjectType.Building);return{foundation:e.foundation,foundationCenter:e.foundationCenter}}getPlayers(){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getNonNeutralPlayers().map(e=>e.name)}getPlayerData(e){let t=GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getPlayerByName(e);if(!t)throw new Error(`Player "${e}" doesn't exist`);return{name:t.name,country:t.country,startLocation:this.map.getStartingLocations()[t.startLocation??0],isObserver:t.isObserver,isAi:t.isAi,isCombatant:t.isCombatant(),credits:t.credits,power:{total:t.powerTrait?.power??0,drain:t.powerTrait?.drain??0,isLowPower:t.powerTrait?.level===PowerLevel.Low},radarDisabled:!!t.radarTrait?.isDisabled()}}getAllTerrainObjects(){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getWorld().getAllObjects().filter(e=>e.isTerrain()).map(e=>e.id)}getAllUnits(t=()=>!0){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getWorld().getAllObjects().filter(e=>e.isTechno()&&t(e.rules)).map(e=>e.id)}getNeutralUnits(t=()=>!0){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getCivilianPlayer().getOwnedObjects().filter(e=>t(e.rules)).map(e=>e.id)}getUnitsInArea(e){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").map.technosByTile.queryRange(e).map(e=>e.id)}getVisibleUnits(e,r,t=()=>!0){const s=GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getPlayerByName(e);if(!s)throw new Error(`Player "${e}" doesn't exist`);if("self"===r)return s.getOwnedObjects().filter(e=>t(e.rules)).map(e=>e.id);let a;if("allied"===r)a=e=>e.owner===s||GameApi_classPrivateFieldGet(this,_GameApi_game,"f").alliances.areAllied(e.owner,s);else{if("hostile"!==r&&"enemy"!==r)throw new Error("Unexpected type "+r);{let i=GameApi_classPrivateFieldGet(this,_GameApi_game,"f").mapShroudTrait.getPlayerShroud(s);a=t=>GameApi_classPrivateFieldGet(this,_GameApi_game,"f").map.tileOccupation.calculateTilesForGameObject(t.tile,t).some(e=>!i?.isShrouded(e,t.tileElevation))&&t.owner!==s&&!GameApi_classPrivateFieldGet(this,_GameApi_game,"f").alliances.areAllied(t.owner,s)&&("enemy"!==r||t.owner.isCombatant())}}return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getWorld().getAllObjects().filter(e=>e.isTechno()&&!e.isDestroyed&&a(e)&&t(e.rules)).map(e=>e.id)}getGameObjectData(t){if(GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getWorld().hasObjectId(t)){let e=GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getObjectById(t);return{id:e.id,type:e.type,name:e.name,rules:e.rules,tile:e.tile,tileElevation:e.tileElevation,worldPosition:e.position.worldPosition.clone(),foundation:e.getFoundation(),hitPoints:e.healthTrait?.getHitPoints(),maxHitPoints:e.healthTrait?.maxHitPoints,owner:e.isTechno()?e.owner.name:void 0}}}getUnitData(t){var i=this.getGameObjectData(t);if(i){let e=GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getObjectById(t);if(!e.isTechno())throw new Error(`Game object with id ${t} is not a Techno type`);return{...i,owner:e.owner.name,sight:e.sight,veteranLevel:e.veteranLevel,guardMode:e.guardMode,purchaseValue:e.purchaseValue,primaryWeapon:e.primaryWeapon?GameApi_classPrivateFieldGet(this,_GameApi_instances,"m",_GameApi_getWeaponData).call(this,e.primaryWeapon):void 0,secondaryWeapon:e.secondaryWeapon?GameApi_classPrivateFieldGet(this,_GameApi_instances,"m",_GameApi_getWeaponData).call(this,e.secondaryWeapon):void 0,deathWeapon:e.armedTrait?.deathWeapon?GameApi_classPrivateFieldGet(this,_GameApi_instances,"m",_GameApi_getWeaponData).call(this,e.armedTrait.deathWeapon):void 0,attackState:e.attackTrait?.attackState,direction:e.direction,onBridge:e.isInfantry()||e.isVehicle()?e.onBridge:void 0,zone:e.isUnit()?e.zone:void 0,buildStatus:e.isBuilding()?e.buildStatus:void 0,factory:e.isBuilding()&&e.factoryTrait?{deliveringUnit:e.factoryTrait.deliveringUnit?.id,status:e.factoryTrait.status}:void 0,rallyPoint:e.isBuilding()?e.rallyTrait?.getRallyPoint():void 0,isPoweredOn:e.isBuilding()&&e.poweredTrait?.isPoweredOn(),hasWrenchRepair:e.isBuilding()&&!e.autoRepairTrait.isDisabled(),turretFacing:e.isBuilding()||e.isVehicle()?e.turretTrait?.facing:void 0,turretNo:e.isVehicle()?e.turretNo:void 0,garrisonUnitCount:e.isBuilding()?e.garrisonTrait?.units.length:void 0,garrisonUnitsMax:e.isBuilding()?e.garrisonTrait?.maxOccupants:void 0,passengerSlotCount:e.isVehicle()?e.transportTrait?.getOccupiedCapacity():void 0,passengerSlotMax:e.isVehicle()?e.transportTrait?.getMaxCapacity():void 0,isIdle:!e.unitOrderTrait.hasTasks(),canMove:e.isUnit()?!e.moveTrait.isDisabled():void 0,velocity:e.isUnit()?e.moveTrait.velocity.clone():void 0,stance:e.isInfantry()?e.stance:void 0,harvestedOre:e.isVehicle()?e.harvesterTrait?.ore:void 0,harvestedGems:e.isVehicle()?e.harvesterTrait?.gems:void 0,ammo:e.isAircraft()?e.ammo:void 0,isWarpedOut:e.warpedOutTrait.isActive(),mindControlledBy:e.mindControllableTrait?.getController()?.id,tntTimer:e.tntChargeTrait?.getTicksLeft()}}}getAllSuperWeaponData(){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").getCombatants().map(t=>t.superWeaponsTrait.getAll().map(e=>({playerName:t.name,type:e.rules.type,status:e.status,timerSeconds:e.getTimerSeconds()}))).flat()}getGeneralRules(){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").rules.general}getRulesIni(){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").rules.getIni()}getArtIni(){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").art.getIni()}getAiIni(){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").ai.getIni()}generateRandomInt(e,t){if(GameApi_classPrivateFieldGet(this,_GameApi_useInternalRng,"f"))return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").generateRandomInt(e,t);var i=this.generateRandom();return Math.floor(i*(t-e+1))+e}generateRandom(){return GameApi_classPrivateFieldGet(this,_GameApi_useInternalRng,"f")?GameApi_classPrivateFieldGet(this,_GameApi_game,"f").generateRandom():Math.random()}getTickRate(){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").speed.value*GameSpeed.BASE_TICKS_PER_SECOND}getBaseTickRate(){return GameSpeed.BASE_TICKS_PER_SECOND}getCurrentTick(){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").currentTick}getCurrentTime(){return GameApi_classPrivateFieldGet(this,_GameApi_game,"f").currentTime/1e3}}function formatTimeDuration(e,t=!1){var i=Math.floor(e/3600);e-=3600*i;var r=Math.floor(e/60),e=e-=60*r;return[...i||!t?[i]:[],pad(r,"00"),pad(e,"00")].join(":")}var _GameApi_game=new WeakMap,_GameApi_useInternalRng=new WeakMap,_GameApi_instances=new WeakSet,_GameApi_getWeaponData=function(e){return{type:e.type,rules:e.rules,projectileRules:e.projectileRules,warheadRules:e.warhead.rules,minRange:e.minRange,maxRange:e.range,speed:e.speed,cooldownTicks:e.getCooldownTicks()}},LoggerApi_classPrivateFieldSet=function(e,t,i,r,s){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!s)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!s:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?s.call(e,i):s?s.value=i:t.set(e,i),i},LoggerApi_classPrivateFieldGet=function(e,t,i,r){if("a"===i&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?r:"a"===i?r.call(e):r?r.value:t.get(e)};class LoggerApi{constructor(e,t){_LoggerApi_instances.add(this),_LoggerApi_logger.set(this,void 0),_LoggerApi_game.set(this,void 0),LoggerApi_classPrivateFieldSet(this,_LoggerApi_logger,e,"f"),LoggerApi_classPrivateFieldSet(this,_LoggerApi_game,t,"f")}setDebugLevel(e){LoggerApi_classPrivateFieldGet(this,_LoggerApi_logger,"f").setLevel(e?AppLogger.DEBUG:AppLogger.WARN)}debug(...e){LoggerApi_classPrivateFieldGet(this,_LoggerApi_logger,"f").debug(LoggerApi_classPrivateFieldGet(this,_LoggerApi_instances,"m",_LoggerApi_getLogPrefix).call(this),...e)}info(...e){LoggerApi_classPrivateFieldGet(this,_LoggerApi_logger,"f").info(LoggerApi_classPrivateFieldGet(this,_LoggerApi_instances,"m",_LoggerApi_getLogPrefix).call(this),...e)}log(...e){LoggerApi_classPrivateFieldGet(this,_LoggerApi_logger,"f").log(LoggerApi_classPrivateFieldGet(this,_LoggerApi_instances,"m",_LoggerApi_getLogPrefix).call(this),...e)}warn(...e){LoggerApi_classPrivateFieldGet(this,_LoggerApi_logger,"f").warn(LoggerApi_classPrivateFieldGet(this,_LoggerApi_instances,"m",_LoggerApi_getLogPrefix).call(this),...e)}error(...e){LoggerApi_classPrivateFieldGet(this,_LoggerApi_logger,"f").error(LoggerApi_classPrivateFieldGet(this,_LoggerApi_instances,"m",_LoggerApi_getLogPrefix).call(this),...e)}time(e){LoggerApi_classPrivateFieldGet(this,_LoggerApi_logger,"f").time(e)}timeEnd(e){LoggerApi_classPrivateFieldGet(this,_LoggerApi_logger,"f").timeEnd(e)}}var _LoggerApi_logger=new WeakMap,_LoggerApi_game=new WeakMap,_LoggerApi_instances=new WeakSet,_LoggerApi_getLogPrefix=function(){return"["+formatTimeDuration(Math.floor(LoggerApi_classPrivateFieldGet(this,_LoggerApi_game,"f").getCurrentTime()))+"]"},ProductionApi_classPrivateFieldSet=function(e,t,i,r,s){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!s)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!s:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?s.call(e,i):s?s.value=i:t.set(e,i),i},ProductionApi_classPrivateFieldGet=function(e,t,i,r){if("a"===i&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?r:"a"===i?r.call(e):r?r.value:t.get(e)};class ProductionApi{constructor(e){_ProductionApi_production.set(this,void 0),ProductionApi_classPrivateFieldSet(this,_ProductionApi_production,e,"f")}isAvailableForProduction(e){return ProductionApi_classPrivateFieldGet(this,_ProductionApi_production,"f").isAvailableForProduction(e)}getAvailableObjects(t){let e=ProductionApi_classPrivateFieldGet(this,_ProductionApi_production,"f").getAvailableObjects();return void 0!==t&&(e=e.filter(e=>this.getQueueTypeForObject(e)===t)),e}getQueueTypeForObject(e){return ProductionApi_classPrivateFieldGet(this,_ProductionApi_production,"f").getQueueTypeForObject(e)}getQueueData(e){let t=ProductionApi_classPrivateFieldGet(this,_ProductionApi_production,"f").getQueue(e);return{size:t.currentSize,maxSize:t.maxSize,status:t.status,type:t.type,items:t.getAll().map(e=>({rules:e.rules,quantity:e.quantity}))}}}var _PlayerApi_gameApi,SlotType,ReplayEventType,ChatRecipientType,_ProductionApi_production=new WeakMap,PlayerApi_classPrivateFieldSet=function(e,t,i,r,s){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!s)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!s:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?s.call(e,i):s?s.value=i:t.set(e,i),i},PlayerApi_classPrivateFieldGet=function(e,t,i,r){if("a"===i&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?r:"a"===i?r.call(e):r?r.value:t.get(e)};class PlayerApi{constructor(e,t,i,r){this.name=e,this.actions=i,this.production=r,_PlayerApi_gameApi.set(this,void 0),PlayerApi_classPrivateFieldSet(this,_PlayerApi_gameApi,t,"f")}getPlayerData(){return PlayerApi_classPrivateFieldGet(this,_PlayerApi_gameApi,"f").getPlayerData(this.name)}isDefeated(){return PlayerApi_classPrivateFieldGet(this,_PlayerApi_gameApi,"f").isPlayerDefeated(this.name)}isAlliedWith(e){return PlayerApi_classPrivateFieldGet(this,_PlayerApi_gameApi,"f").areAlliedPlayers(this.name,e)}canPlaceBuilding(e,t){return PlayerApi_classPrivateFieldGet(this,_PlayerApi_gameApi,"f").canPlaceBuilding(this.name,e,t)}getVisibleUnits(e,t=()=>!0){return PlayerApi_classPrivateFieldGet(this,_PlayerApi_gameApi,"f").getVisibleUnits(this.name,e,t)}}_PlayerApi_gameApi=new WeakMap;class BotContext{constructor(e,t,i){this.game=e,this.player=t,this.logger=i}}class BotManager{static factory(e,t,i,r){return new this(e,new ActionQueue,t,i,r)}constructor(e,t,i,r,s){this.actionFactory=e,this.actionQueue=t,this.botFactory=i,this.botDebugIndex=r,this.actionLogger=s,this.bots=new Map,this.disposables=new CompositeDisposable}init(t){this.gameApi=new GameApi(t,!0);let e=new EventsApi(t.events);var i,r;for(i of t.getCombatants().filter(e=>e.isAi))this.bots.set(i,this.botFactory.create(i));this.updateDebugBotIndex(this.botDebugIndex.value,t);let s=e=>this.updateDebugBotIndex(e,t);this.botDebugIndex.onChange.subscribe(s),this.disposables.add(()=>this.botDebugIndex.onChange.unsubscribe(s)),e.subscribe(t=>this.bots.forEach(e=>e.onGameEvent(t,this.gameApi))),this.disposables.add(e);for(r of this.bots.values()){var a=new PlayerApi(r.name,this.gameApi,new ActionsApi(t,this.actionFactory,this.actionQueue,r),new ProductionApi(t.getPlayerByName(r.name).production)),n=new LoggerApi(AppLogger.get(r.name),this.gameApi);r.setGameApi(this.gameApi),r.setActionsApi(a.actions),r.setProductionApi(a.production),r.setLogger(n),r.setContext?.(new BotContext(this.gameApi,a,n)),r.onGameInit?.(this.gameApi)}}onGameStart(){if(!this.gameApi)throw new Error("Bot manager is not initialized");for(var e of this.bots.values())e.onGameStart(this.gameApi)}update(e){var t,i;for(t of this.actionQueue.dequeueAll()){t.process();var r=t.print();r&&this.actionLogger.debug(`(${t.player.name})@${e.currentTick}: `+r)}for(i of e.getCombatants().filter(e=>e.isAi))this.bots.get(i).onGameTick(this.gameApi)}updateDebugBotIndex(e,t){var i,r=0<e?t.getAiPlayerName(e):void 0;for(i of this.bots.values())i.setDebugMode(i.name===r)}dispose(){this.gameApi=void 0,this.bots.clear(),this.disposables.dispose()}}class GameFactory{static create(e,t,i,r,s,a,n,o,l,h,c,d,u,p,g,m,y){let T=i.clone().mergeWith(a);for(var f of n)T.mergeWith(f);T.mergeWith(e);var v=r.clone().mergeWith(e.artOverrides??new IniFile);let b=new Rules(T,p);a=new Art(b,v,e,p),n=new Ai(s);b.applySpecialFlags(e.specialFlags),GameOptSanitizer.sanitize(h,b);let w=new Rules(i),S=w.getMultiplayerCountries(),A=[...w.getMultiplayerColors().values()],_=Prng.factory(o,l),O=new GameMap(e,t,b,_.generateRandomInt.bind(_));r=new World,v=c.getById(h.gameMode).type,p=new PlayerList,s=new Alliances(p),i=new UnitSelection,e=new BoxedVar(1),t=new ObjectFactory(O.tiles,O.tileOccupation,O.bridges,e),c=new ActionFactory,u=new BotFactory(u),y=BotManager.factory(c,u,m,y);let E=new Game(r,O,b,a,n,o,l,h,v,p,i,s,e,t,y);(new ActionFactoryReg).register(c,E,void 0),E.traits.add(new PowerTrait_PowerTrait),E.sellTrait=new SellTrait(E,b.general),E.traits.add(E.sellTrait),E.traits.add(new RadarTrait_RadarTrait);let C=new ProductionTrait(b,g);E.traits.add(C),E.mapShroudTrait=new MapShroudTrait(O,s),E.traits.add(E.mapShroudTrait),E.mapRadiationTrait=new MapRadiationTrait(O),E.traits.add(E.mapRadiationTrait),E.mapLightingTrait=new MapLightingTrait(b.audioVisual,O.getLighting()),E.traits.add(E.mapLightingTrait),E.traits.add(new SuperWeaponsTrait),E.traits.add(new SharedDetectDisguiseTrait_SharedDetectDisguiseTrait),E.traits.add(new SharedDetectCloakTrait),E.crateGeneratorTrait=new CrateGeneratorTrait(h.cratesAppear),E.traits.add(E.crateGeneratorTrait),d||(E.stalemateDetectTrait=new StalemateDetectTrait,E.traits.add(E.stalemateDetectTrait));let k=new PlayerFactory(b,h,C.getAvailableObjects()),P=GameOptRandomGen.factory(o,l),I=P.generateColors(h),B=P.generateCountries(h,w),N=P.generateStartLocations(h,O.startingLocations),R=[...h.humanPlayers,...h.aiPlayers].filter(isNotNullOrUndefined);return R.forEach(e=>{let t,i,r;if(isHumanPlayerInfo(e)?(t=e.name,i=!1):(t=E.getAiPlayerName(e),i=!0,r=e.difficulty),e.countryId!==OBS_COUNTRY_ID){var s=B.get(e)??e.countryId,a=I.get(e)??e.colorId,e=N.get(e)??e.startPos;if(s===RANDOM_COUNTRY_ID)throw new Error("Random country should have been resolved by now");if(a===RANDOM_COLOR_ID)throw new Error("Random color should have been resolved by now");if(e===RANDOM_START_POS)throw new Error("Random start location should have been resolved by now");s=S[s].name,s=Country.factory(s,b),a=A[a];E.addPlayer(k.createCombatant(t,s,e,a,i,r))}else E.addPlayer(k.createObserver(t,b))}),E.addPlayer(k.createNeutral(b,"@@NEUTRAL@@")),E}}class AiPlayTurnManager{constructor(e,t,i,r,s,a){this.game=e,this.inputActions=t,this.replayRecorder=i,this.actionSerializer=r,this.actionFactory=s,this.actionLogger=a,this.errorState=!1}init(){this.gameTurnMillis=1e3/(this.game.speed.value*GameSpeed.BASE_TICKS_PER_SECOND)}setErrorState(){this.errorState=!0}getErrorState(){return this.errorState}getTurnMillis(){return this.gameTurnMillis}doGameTurn(){if(!this.errorState){if(this.game.status!==GameStatus.Ended){var t,e=this.inputActions.dequeueAll();const r=new Map;for(t of e){var i=this.actionSerializer.getActionPayload(t);let e=r.get(t.player);e||(e=[],r.set(t.player,e)),e.push(i)}this.replayRecorder.recordActions(this.game.currentTick,new Map([...r].map(([e,t])=>[this.game.getPlayerNumber(e),t]))),r.forEach((t,i)=>{if(!t.length){let e=new NoAction;e.player=i,t.push(this.actionSerializer.getActionPayload(e))}}),this.processActions(r)}this.game.update()}}processActions(e){[...e].forEach(([i,e])=>e.forEach(e=>{let t=this.actionFactory.create(e.id);t.player=i,t.unserialize(e.params),t.process();e=t.print();e&&this.actionLogger?.debug(`(${i.name})@${this.game.currentTick}: `+e)}))}dispose(){}}!function(e){e[e.Closed=0]="Closed",e[e.Open=1]="Open",e[e.OpenObserver=2]="OpenObserver",e[e.Player=3]="Player",e[e.Ai=4]="Ai"}(SlotType=SlotType||{});class MapNameLegacyEncoder{encode(e){let r=[],s=0;return e.split("").forEach((e,t)=>{var i=e.charCodeAt(0)<<2*t-7*s,e=127&i,t=i>>7&127,i=i>>14&127;i&&s++,r.push(e,t),i&&r.push(i)}),r.push(0,0),2<=e.length&&r.push(0),r=r.map(e=>128^e),r.map(e=>String.fromCharCode(e)).join("")}decode(e){let i=e.split("").map(e=>e.charCodeAt(0));for(i=i.map(e=>128^e);0===i[i.length-1];)i.pop();let r=[],s=0,a=0;for(;i.length;){var n=r.length,o=i.shift(),l=i.shift();let e=0,t=!1;(-1!==[1,2,3].indexOf(i[0])||n>s+3)&&(e=i.shift(),s=n,t=!0);n=(e<<14|l<<7|o)>>2*n-7*a;r.push(127&n),t&&a++}return r.map(e=>String.fromCharCode(e)).join("")}}class FileNameEncoder{encode(e){return e.match(/^[a-z0-9-_]+\.[a-z]{3}$/i)?e:Base64.encode(utf16ToBinaryString(e))}decode(e){return e.match(/\.[a-z]{3}$/i)?e:binaryStringToUtf16(Base64.decode(e))}}class Serializer{serializeOptions(e,t=!1){let i=e.gameMode,r=t?(new MapNameLegacyEncoder).encode(e.mapTitle):Base64.encode(utf16ToBinaryString(e.mapTitle)),s=(new FileNameEncoder).encode(e.mapName);t=["0","0",6-e.gameSpeed,e.credits,e.unitCount,Number(e.shortGame),Number(e.superWeapons),Number(e.buildOffAlly),Number(e.mcvRepacks),Number(e.cratesAppear),i,Number(e.hostTeams??!1),r,e.maxSlots,Number(e.mapOfficial),e.mapSizeBytes,s,e.mapDigest,Number(e.destroyableBridges),Number(e.multiEngineer),Number(e.noDogEngiKills),...e.unknown?[e.unknown]:[]].join(",");return t+`:${e.humanPlayers.map(e=>""+e.name+`,${e.countryId},${e.colorId},${e.startPos},${e.teamId},0,0,0`).join(",")}:@:${this.serializeAiOpts(e.aiPlayers)},`}serializeAiOpts(e){return e.map(e=>e?`${e.difficulty},${e.countryId},${e.colorId},${e.startPos},`+e.teamId:"0,-1,-1,-1,-1").join(",")}serializePingData(e){return e.length+","+e.map(e=>e.playerName+","+e.ping).join(",")}serializeSlotData(e){return e.map(e=>{if(e.type===SlotType.Closed)return"@Closed@";if(e.type===SlotType.Open)return"@Open@";if(e.type===SlotType.OpenObserver)return"@OpenObserver@";if(e.type===SlotType.Ai){if(e.difficulty===AiDifficulty.Easy)return"@EasyAI@";if(e.difficulty===AiDifficulty.Medium)return"@MediumAI@";if(e.difficulty===AiDifficulty.Brutal)return"@HardAI@"}else if(e.type===SlotType.Player)return e.name;throw new Error("Unexpected slot info with type "+SlotType[e.type])}).join(",")+","}serializeLoadInfo(e){return e.map(e=>[e.name,e.status,e.loadPercent,e.ping,e.lagAllowanceMillis].join(",")).join(",")}serializePlayerActions(e){let t=new DataStream;t.writeUint8(e.length);for(var{id:i,params:r}of e)if(t.writeUint8(i),t.writeUint16(r.byteLength),0<r.byteLength){if(r.byteLength>Serializer.MAX_ACTION_PAYLOAD_SIZE-t.position)throw console.error(`Action #${i} payload exceeds max data size`,r),new RangeError("Maximum payload data size exceeded");t.writeUint8Array(r)}return t.toUint8Array()}serializeAllPlayerActions(e,t){e.writeUint8(t.size);for(var[i,r]of t){e.writeUint8(i);var s=this.serializePlayerActions(r);if(e.writeUint16(s.byteLength),0<s.byteLength){if(s.byteLength>Serializer.MAX_ACTION_PAYLOAD_SIZE)throw console.error(`Player #${i} actions payload exceeds max data size`,r),new RangeError("Maximum payload data size exceeded");e.writeUint8Array(s)}}}serializeMapData(e){return binaryStringToUint8Array(e)}}Serializer.MAX_ACTION_PAYLOAD_SIZE=65536;class Parser{parseOptions(e){let t={},[i,r,,s]=e.split(":"),a=i.split(",");a.shift(),a.shift(),t.gameSpeed=6-Number(a.shift()),t.credits=Number(a.shift()),t.unitCount=Number(a.shift()),t.shortGame=Boolean(Number(a.shift())),t.superWeapons=Boolean(Number(a.shift())),t.buildOffAlly=Boolean(Number(a.shift())),t.mcvRepacks=Boolean(Number(a.shift())),t.cratesAppear=Boolean(Number(a.shift())),t.gameMode=Number(a.shift()),t.hostTeams=Boolean(Number(a.shift()));e=a.shift();return t.mapTitle=Base64.isBase64(e)?binaryStringToUtf16(Base64.decode(e)):(new MapNameLegacyEncoder).decode(e),t.maxSlots=Number(a.shift()),t.mapOfficial=Boolean(Number(a.shift())),t.mapSizeBytes=Number(a.shift()),t.mapName=(new FileNameEncoder).decode(a.shift()),t.mapDigest=a.shift(),t.destroyableBridges=Boolean(Number(a.shift()??"1")),t.multiEngineer=Boolean(Number(a.shift()??"0")),t.noDogEngiKills=Boolean(Number(a.shift()??"0")),t.unknown=a.length?a.join(","):void 0,t.humanPlayers=this.parsePlayerOpts(r),t.aiPlayers=this.parseAiOpts(s?.slice(0,-1)),t}parsePlayerOpts(e){var i=e.split(",");if(i.length%8!=0)throw new Error("Couldn't parse gameopt: unexpected players data length "+i.length);let r=[];for(let e=0,t=Math.floor(i.length/8);e<t;++e){var s={name:i[8*e],countryId:Number(i[8*e+1]),colorId:Number(i[8*e+2]),startPos:Number(i[8*e+3]),teamId:Number(i[8*e+4])};r.push(s)}return r}parseAiOpts(e){let i=[];if(e){var r=e.split(",");if(r.length%5!=0)throw new Error("Couldn't parse gameopt: unexpected ai data length "+r.length);for(let e=0,t=Math.floor(r.length/5);e<t;++e){var s={difficulty:Number(r[5*e]),countryId:Number(r[5*e+1]),colorId:Number(r[5*e+2]),startPos:Number(r[5*e+3]),teamId:Number(r[5*e+4])};i.push(-1!==s.countryId?s:void 0)}}return i}parseTopic(e){var t=e.split(",");if(!(t.length<6)){var i=t[0],r=Number(t[1]),s=i[2],a=t[2],n=t[3],e=t[4],i=(new FileNameEncoder).decode(t[5]);return{description:t[6]?binaryStringToUtf16(Base64.decode(t[6])):"",modHash:r,modName:t[7]?binaryStringToUtf16(Base64.decode(t[7])):void 0,aiPlayers:Number(a),maxPlayers:Number(s),observers:Number(n),observable:Boolean(Number(e)),mapName:i}}}parsePingData(e){var i=e.split(",").slice(1);if(i.length%2)throw new Error("Couldn't parse gameopt: unexpected ping data length "+i.length);let r=[];for(let e=0,t=Math.floor(i.length/2);e<t;++e)r.push({playerName:i[2*e],ping:Number(i[2*e+1])});return r}parseSlotData(e){var i;let r=[];for(i of e.slice(1,-1).split(",")){let t={};if("@Closed@"===i)t.type=SlotType.Closed;else if("@Open@"===i)t.type=SlotType.Open;else if("@OpenObserver@"===i)t.type=SlotType.OpenObserver;else if(-1!==["@EasyAI@","@MediumAI@","@HardAI@"].indexOf(i)){t.type=SlotType.Ai;let e;if("@EasyAI@"===i)e=AiDifficulty.Easy;else if("@MediumAI@"===i)e=AiDifficulty.Medium;else{if("@HardAI@"!==i)throw new Error("Couldn't parse gameopt: unknown slot type "+i);e=AiDifficulty.Brutal}t.difficulty=e}else t.type=SlotType.Player,t.name=i;r.push(t)}return r}parsePlayerActions(e){let t=new DataStream(e);var i=t.readUint8();let r=[];for(let e=0;e<i;++e){var s=t.readUint8(),a=t.readUint16(),a=0<a?t.readUint8Array(a):new Uint8Array;r.push({id:s,params:a})}return r}parseAllPlayerActions(t){var i=t.readUint8();let r=new Map;for(let e=0;e<i;++e){var s=t.readUint8(),a=t.readUint16(),a=0<a?t.readUint8Array(a):new Uint8Array,a=this.parsePlayerActions(a);r.set(s,a)}return r}parseMapData(e){return uint8ArrayToBinaryString(e)}}class ReplayEvent{constructor(e,t){this.type=e,this.tickNo=t}}!function(e){e[e.TurnActions=0]="TurnActions",e[e.ChatMessage=1]="ChatMessage",e[e.Taunt=2]="Taunt"}(ReplayEventType=ReplayEventType||{});class ChatMessageReplayEvent extends ReplayEvent{constructor(e){super(ReplayEventType.ChatMessage,e)}serialize(){return this.payload.playerId+":"+Base64.encode(utf16ToBinaryString(this.payload.message))}unserialize(e){var[t,e]=e.split(":"),t=Number(t),e=binaryStringToUtf16(Base64.decode(e));this.payload={playerId:t,message:e}}}class TauntReplayEvent extends ReplayEvent{constructor(e){super(ReplayEventType.Taunt,e)}serialize(){return this.payload.playerId+":"+this.payload.tauntNo}unserialize(e){var[t,e]=e.split(":"),t=Number(t),e=Number(e);this.payload={playerId:t,tauntNo:e}}}class TurnActionsReplayEvent extends ReplayEvent{constructor(e,t,i){super(ReplayEventType.TurnActions,i),this.gameOptsParser=e,this.gameOptsSerializer=t}serialize(){let e=new DataStream;return this.gameOptsSerializer.serializeAllPlayerActions(e,new Map(this.payload)),uint8ArrayToBase64String(e.toUint8Array())}unserialize(e){e=new DataStream(base64StringToUint8Array(e)),e=this.gameOptsParser.parseAllPlayerActions(e);this.payload=[...e]}}class ReplayEventFactory{constructor(e,t){this.gameOptsParser=e,this.gameOptsSerializer=t}create(e,t){switch(e){case ReplayEventType.TurnActions:return new TurnActionsReplayEvent(this.gameOptsParser,this.gameOptsSerializer,t);case ReplayEventType.ChatMessage:return new ChatMessageReplayEvent(t);case ReplayEventType.Taunt:return new TauntReplayEvent(t);default:throw new Error(`Unsupported replay event type "${e}" at game tick "${t}"`)}}}async function*makeTextFileLineIterator(e){const t=new TextDecoder("utf-8");let i=e.stream().getReader(),{value:r,done:s}=await i.read();r=r?t.decode(r,{stream:!0}):"";let a=/\r\n|\n|\r/gm,n=0;for(;;){var o=a.exec(r);if(o)yield r.substring(n,o.index),n=a.lastIndex;else{if(s)break;o=r.substr(n);({value:r,done:s}=await i.read()),r=o+(r?t.decode(r,{stream:!0}):""),n=a.lastIndex=0}}n<r.length&&(yield r.substr(n))}const REPLAY_VERSION=6,supportedReplayVersions=[5,6];class Replay{constructor(){this.name="",this.events=[]}static sanitizeFileName(e,t="_"){return e.replace(/[/?<>\\:*|"]/g,t).replace(/[\x00-\x1f\x7f\x80-\x9f]/g,t).slice(0,this.maxNameLength)}init(e,t,i,r,s){this.gameId=e,this.gameTimestamp=t,this.gameOpts=i,this.engineVersion=r,this.modHash=s,this.name=Replay.sanitizeFileName(this.gameOpts.mapTitle+" "+(new Date).toISOString().replace(/(\.|,)\d+Z$/,"Z")),this.timestamp=Date.now()}writeEvent(...e){this.events.push(...e)}finish(e){this.endTick=e}getEvents(){return this.events}*flush(){if(!this.gameOpts)throw new Error("Game options must be set first");if(!this.engineVersion)throw new Error("Engine version is not set");if(void 0===this.modHash)throw new Error("Mod hash is not set");let e=new Serializer,t=this.getHeaderTag()+"\n";for(t+=`ENGINE ${this.engineVersion} ${this.modHash}
2
+ `,t+=[this.gameId,this.gameTimestamp,e.serializeOptions(this.gameOpts)].join(" ")+"\n",yield t,t="";void 0===this.endTick||this.events.length;){for(var i of this.events)t+=i.tickNo+"="+i.type+"|"+i.serialize()+"\n";this.events.length=0,yield t,t=""}t+=this.getEndTag()+" "+this.endTick+"\n",this.debugInfo&&(t+=Base64.encode(utf16ToBinaryString(this.debugInfo))+"\n"),yield t}serialize(){if(void 0===this.endTick)throw new Error("Replay is not finished");let e="";var t,i=this.events.slice();for(t of this.flush())e+=t;return this.events=i,e}async parseHeader(e){let t=0,i,r,s,a,n,o;var l;for await(l of"string"==typeof e?e.split("\n"):makeTextFileLineIterator(e)){if(0===t)i=this.readReplayVersion(l);else if(1===t){if(!l.match(Replay.engineLineRegex))throw new Error("Missing or invalid game engine version line");var h=l.split(" ");r=h[1],s=Number(i<4?"0":h[2])}else{if(2!==t)break;if(!l.match(/^([a-zA-Z0-9-]+) \d+ .*$/))throw new Error("Missing or invalid game id/time/opts line");var[c,d,h]=l.split(" ");a=c,n=Number(d),o=i<6?Base64.decode(h):h}t++}if(t<3)throw new Error("Bad replay header");return{replayVersion:i,engineVersion:r,modHash:s,gameId:a,gameTimestamp:n,gameOptsSerialized:o}}unserialize(e,t){let i=e.split("\n");var r=this.readReplayVersion(i.shift()||"");if(!supportedReplayVersions.includes(r))throw new Error("Unsupported replay version "+r);let s=new Parser,a=i.shift();if(!a||!a.match(Replay.engineLineRegex))throw new Error("Missing or invalid game engine version line");var[,n,o]=a.split(" ");let l=i.shift();if(!l)throw new Error("Missing game id/time/opts line");e=l.match(/^([a-zA-Z0-9-]+) (\d+) (.*)$/);if(!e)throw new Error("Invalid game id/time/opts line");let[,h,c,d]=e;r<6&&(d=Base64.decode(d));r=s.parseOptions(d);this.init(h,Number(c),r,n,Number(o)),this.name=t.name,this.timestamp=t.timestamp;let u,p=!1;for(;u=i.shift();){if(u.startsWith(this.getEndTag())){p=!0;break}var g=u.match(/^(\d+)=(\d+)\|(.+)$/);if(!g)throw new Error(`Invalid event line "${u}"`);var[,m,y,g]=g,m=Number(m),y=Number(y);let e=new ReplayEventFactory(s,new Serializer).create(y,m);e.unserialize(g),this.writeEvent(e)}if(!p)throw new Error("Incomplete replay data");t=u.match(new RegExp(`^${this.getEndTag()} (\\d+)$`));if(!t)throw new Error("Invalid end tag");this.endTick=Number(t[1]),1<=i.length&&(this.debugInfo=binaryStringToUtf16(Base64.decode(i[0])))}getHeaderTag(){return"RA2TSREPL_v"+REPLAY_VERSION}readReplayVersion(e){e=e.match(/^RA2TSREPL_v(\d+)$/);if(!e||e.length<2)throw new Error("Unknown replay format");return Number(e[1])}getEndTag(){return"END"}}Replay.extension=".rpl",Replay.maxNameLength=128,Replay.engineLineRegex=/^ENGINE \d+\.\d+( \d+)?$/;class ReplayRecorder{constructor(e,t,i,r){this.replay=e,this.playerId=t,this.humanPlayers=i,this.actionSerializer=r}recordActions(t,i){if(Array.isArray(i)){let e=new TurnActionsReplayEvent(new Parser,new Serializer,t);e.payload=[[this.playerId,i.map(e=>this.actionSerializer.getActionPayload(e))]],this.replay.writeEvent(e)}else if(this.hasActualActions(i)){let e=new TurnActionsReplayEvent(new Parser,new Serializer,t);e.payload=[...i].map(([e,t])=>[e,t]),this.replay.writeEvent(e)}}recordChatMessage(e,t,i){let r=new ChatMessageReplayEvent(e);r.payload={playerId:this.humanPlayers.findIndex(e=>e.name===t),message:i},this.replay.writeEvent(r)}recordTaunt(e,t,i){let r=new TauntReplayEvent(e);r.payload={playerId:this.humanPlayers.findIndex(e=>e.name===t),tauntNo:i},this.replay.writeEvent(r)}hasActualActions(e){return!![...e.values()].find(e=>e.find(e=>e.id!==ActionType.NoAction))}}class ActionSerializer{getActionPayload(e){return{id:e.actionType,params:e.serialize()}}}class OperationCanceledError extends Error{constructor(e){super(),this.cancellationToken=e}}const CANCEL=Symbol(),REGISTER=Symbol();class CancellationToken{constructor(e){this.source=e,this.cancelled=!1}throwIfCancelled(){if(this.isCancelled())throw new OperationCanceledError(this)}isCancelled(){return!0===this.cancelled}[CANCEL](){this.cancelled=!0}register(e){this.source[REGISTER](e)}}class EventDispatcher_EventDispatcher{constructor(){this.listeners=new Set}subscribe(e){this.listeners.add(e)}unsubscribe(e){this.listeners.delete(e)}subscribeOnce(i){let r=(e,t)=>{i(e,t),this.unsubscribe(r),r=void 0};this.subscribe(r)}dispatch(t,i){this.listeners.forEach(e=>e(i,t))}asEvent(){return this}}class CancellationTokenSource{constructor(){this.onCancel=new EventDispatcher_EventDispatcher,this.token=new CancellationToken(this)}cancel(){this.token[CANCEL](),this.onCancel.dispatch(this,void 0)}[REGISTER](e){this.onCancel.subscribe(()=>e()),this.token.isCancelled()&&e()}}async function sleep(t){return new Promise(e=>{setTimeout(()=>e(),t)})}function throttle(r,s){let a=!1,n=Number.NEGATIVE_INFINITY;return async function(...e){var t,i;a||(i=(t=Date.now())-n,n=s<=i?t:(a=!0,await sleep(s-i),a=!1,Date.now()),await r.apply(this,e))}}function Throttle(s){return(e,t,i)=>{var r=i.value;i.value=throttle(r,s)}}class IrcConnection{constructor(e,t){this.options=e,this.logger=t,this.timeout=5,this._onMessage=new EventDispatcher,this._onError=new EventDispatcher,this._onClose=new EventDispatcher,this.messageBuffer=""}get onMessage(){return this._onMessage.asEvent()}get onError(){return this._onError.asEvent()}get onClose(){return this._onClose.asEvent()}async connect(r,s){let e=s?.timeoutSeconds?setTimeout(()=>this.close(),1e3*s.timeoutSeconds):void 0;return s?.cancelToken?.register(()=>{e&&(clearTimeout(e),this.close())}),new Promise((e,t)=>{this.socket=new WebSocket(r),"arraybuffer"!==this.socket.binaryType&&(this.socket.binaryType="arraybuffer");let i=e=>{this.socket.removeEventListener("error",i),s?.cancelToken?.isCancelled()?t(new OperationCanceledError(s.cancelToken)):t(new IrcConnection.ConnectError(`Connection to "${r}" failed`))};this.socket.addEventListener("open",()=>{this.socket.removeEventListener("error",i),this.socket.addEventListener("error",e=>this.handleError(e)),this.handleOpen(),e()}),this.socket.addEventListener("error",i),this.socket.addEventListener("close",e=>this.handleClose(e)),this.socket.addEventListener("message",e=>{e.data instanceof ArrayBuffer?this.handleMessage(new Uint8Array(e.data)):this.handleMessage(e.data)})}).finally(()=>{e&&clearTimeout(e)})}handleOpen(){this.logger.info("Connection open to "+this.socket.url)}handleError(e){this.logger.error("Connection error",e),this._onError.dispatch(this,e)}handleClose(e){this.logger.info(`Connection closed (${this.socket.url})`,e),this._onClose.dispatch(this,e)}handleMessage(e){if("string"!=typeof e){if(e[0]===this.options.binaryRplPrefix)return void this._onMessage.dispatch(this,e.slice(1));e=uint8ArrayToBinaryString(e)}this.logger.enabledFor(AppLogger.DEBUG)&&this.logger.debug("Got message:","string"==typeof e?this.options.logFilter?.(e)??e:e),e=this.messageBuffer+e,this.messageBuffer="";let t=e.split(/\r?\n/);e=t.pop();e.length&&(this.messageBuffer=e),t.filter(e=>!!e).forEach(e=>this._onMessage.dispatch(this,e))}async sendCommand(e,l){if(l.replyStartCode&&!l.replyEndCode)throw new Error("Invalid argument. Expected a reply end code, but got only a start code.");let h=[];return await this.sendRawCommand(e,(e,s,a,n)=>{let o=(e,t)=>{if("number"==typeof e)return t.code===e;let[i,r]=e;return t.code===i&&r(t)};if("string"!=typeof e){if(e[0]===this.options.binaryRplPrefix)return!1;e=uint8ArrayToBinaryString(e)}return l.replyRawText?(a(e.split(/\r?\n/).map(e=>({raw:e,time:s}))),!0):e.split(/\r?\n/).filter(e=>!!e).some(e=>(e=>{if(l.replyMatch){if(l.replyMatch.exec(e))return a([{raw:e,time:s}]),!0;if(!l.replyCodes)return!1}if(!l.replyEndCode&&!l.replyCodes)return a([{raw:e,time:s}]),!0;var[,t,...i]=e.split(" "),t=parseInt(t,10);let r={raw:e,code:t,params:i,time:s};if(l.replyEndCode)return l.replyCodes&&l.replyCodes.some(e=>o(e,r))?(a([r]),!0):(l.replyHeartbeatCodes&&-1!==l.replyHeartbeatCodes.indexOf(t)&&n(l.heartbeatTimeout),(t===l.replyStartCode||l.replyBodyCodes&&-1!==l.replyBodyCodes.indexOf(t)||t===l.replyEndCode)&&h.push(r),t===l.replyEndCode&&(a(h),!0));if(void 0===l.replyCodes)throw new Error("List of replyCodes must be specified when not using start/end codes");return!!l.replyCodes.some(e=>o(e,r))&&(a([r]),!0)})(e))},l.timeout)}async sendBinCommand(e,s){const a=this.options.binaryRplPrefix;if(!a)throw new Error("Must configure binary message reply prefix to send binary commands");const t=this.options.binaryReqPrefix;if(!t)throw new Error("Must configure binary message request prefix to send binary commands");if(e[0]!==t)throw new Error("Binary command must start with the magic prefix 0x"+t.toString(16));return await this.sendRawCommand(e,(e,t,i)=>{if("string"==typeof e||e[0]!==a)return!1;var r=e[1];return-1!==s.replyCodes.indexOf(r)&&(i({code:r,data:e.slice(2),time:t}),!0)},s.timeout)}sendRawCommand(d,u,p){return new Promise((t,i)=>{let e=!1,r,s=e=>{clearTimeout(r),void 0!==e&&Number.isFinite(e)&&(r=setTimeout(o,1e3*(e??p??this.timeout)))},a=e=>{clearTimeout(r),t(e)},n=e=>{this.socket.removeEventListener("message",c),this.socket.removeEventListener("close",l),clearTimeout(r),r=void 0,i(e)},o=()=>{var e="string"==typeof d?this.options.logFilter?.(d)??d:"0x"+d[1].toString(16);n(new IrcConnection.NoReplyError("Timeout reached for command "+e))},l=async()=>{for(;e;)await sleep(10);h||n(new IrcConnection.SocketError("Connection was closed prematurely"))},h=!1,c=e=>{var t;h||(t=Date.now(),e.data instanceof ArrayBuffer?h||u(new Uint8Array(e.data),t,a,s)&&(h=!0,this.socket.removeEventListener("message",c),this.socket.removeEventListener("close",l)):u(e.data,t,a,s)&&(h=!0,this.socket.removeEventListener("message",c),this.socket.removeEventListener("close",l)))};if(this.socket&&this.socket.readyState===WebSocket.OPEN){r=setTimeout(o,1e3*(p??this.timeout)),this.socket.addEventListener("message",c),this.socket.addEventListener("close",l);try{this.sendMessage(d)}catch(e){n(e)}}else n(new IrcConnection.SocketError("Send command failed. Socket is not open."+(this.socket?` (readyState = ${this.socket.readyState})`:"")))})}sendMessage(e){if(!this.socket||this.socket.readyState!==WebSocket.OPEN)throw new IrcConnection.SocketError("Socket is not open"+(this.socket?` (readyState = ${this.socket.readyState})`:""));this.logger.enabledFor(AppLogger.DEBUG)&&this.logger.debug("Sent message:","string"==typeof e?this.options.logFilter?.(e)??e:e),"string"==typeof e&&(e+="\r\n");let t;t="binary"===this.options.mode&&"string"==typeof e?binaryStringToUint8Array(e):e,this.socket.send(t)}async ping(e){var t=Date.now();return(await this.sendCommand("ping :"+t,{replyMatch:new RegExp("^:[^ ]+ PONG [^ :]+ :"+t,"i"),timeout:e}))[0].time-t}close(){this.socket&&this.socket.close()}isOpen(){return this.socket&&this.socket.readyState===WebSocket.OPEN}}!function(e){class t extends Error{constructor(e){super(e)}}e.NoReplyError=t;class i extends Error{constructor(e){super(e)}}e.SocketError=i;class r extends Error{constructor(e){super(e)}}e.ConnectError=r}(IrcConnection=IrcConnection||{});const RPL_CVERS_OK=10,RPL_CVERS_OUTDATED=11,RPL_CVERS_MISSING=12,RPL_LOGGED_IN=100,RPL_ALREADY_LOGGED_IN=101,RPL_NOT_LOGGED_IN=102,RPL_BAD_LOGIN=103,RPL_TOO_MANY_LOGIN_ATTEMPTS=104,RPL_INSTANCE_CREATED=200,RPL_INSTANCE_EXISTS=201,RPL_INSTANCE_TOO_MANY=202,RPL_NOT_ENOUGH_PARAMS=300,RPL_INVALID_PARAMS=301,RPL_RATE_LIMIT_EXCEEDED=302,RPL_INSTANCE_CONNECTED=400,RPL_INSTANCE_NONEXISTENT=401,RPL_INSTANCE_NOT_ALLOWED=402,RPL_INSTANCE_ALREADY_STARTED=403,RPL_NO_INSTANCE=404,RPL_INSTANCE_NOT_RUNNING=405,RPL_INSTANCE_VERS_MISMATCH=406,RPL_GAME_OPTS=500,RPL_LOAD_INFO=600,RPL_MAP_TOO_BIG=602,RPL_MAP_ALREADY_SENT=603,RPL_GAME_START=700,RPL_GAME_DESYNC=801,RPL_NET_RATE=802,RPL_TAUNT=803,RPL_PLAYER_DISCONNECT=804,RPL_PRIVMSG_NOT_ALLOWED=805,RPL_BIN_PREFIX=2,RPL_BIN_GAME_ACTIONS=1,RPL_BIN_MAP_DATA=2,REQ_BIN_PREFIX=2,REQ_BIN_GAME_ACTIONS=1,REQ_BIN_GAME_STATE_HASH=2,REQ_BIN_PUT_MAP=3,REQ_BIN_GET_MAP=4;class GservError extends Error{constructor(e,t){super(e),this.code=t}}!function(e){(e=e.Code||(e.Code={}))[e.Unknown=0]="Unknown",e[e.OutdatedClient=1]="OutdatedClient",e[e.BadLogin=2]="BadLogin",e[e.TooManyLoginAttempts=3]="TooManyLoginAttempts",e[e.AlreadyLoggedIn=4]="AlreadyLoggedIn",e[e.InstanceNonExistent=5]="InstanceNonExistent",e[e.InstanceAlreadyExists=6]="InstanceAlreadyExists",e[e.InstanceNotAllowed=7]="InstanceNotAllowed",e[e.InstanceAlreadyStarted=8]="InstanceAlreadyStarted",e[e.InstanceVersMismatch=9]="InstanceVersMismatch",e[e.CreatedTooManyInstances=10]="CreatedTooManyInstances"}(GservError=GservError||{});const API_VERSION=2,RECIPIENT_ALL="#all",RECIPIENT_TEAM="#team",TURN_TIMEOUT_MILLIS=3e4,LAG_STATE_THRESH_MILLIS=1e3,CON_INFO_THRESH_MILLIS=2e3,LAG_CHECK_INTERVAL_MILLIS=1e3,MAX_MAP_TRANSFER_BYTES=2097152;!function(e){e[e.Channel=0]="Channel",e[e.Page=1]="Page",e[e.Whisper=2]="Whisper"}(ChatRecipientType=ChatRecipientType||{});const gservErrorCodeMap=new Map([[RPL_BAD_LOGIN,GservError.Code.BadLogin],[RPL_TOO_MANY_LOGIN_ATTEMPTS,GservError.Code.TooManyLoginAttempts],[RPL_ALREADY_LOGGED_IN,GservError.Code.AlreadyLoggedIn],[RPL_INSTANCE_EXISTS,GservError.Code.InstanceAlreadyExists],[RPL_INSTANCE_TOO_MANY,GservError.Code.CreatedTooManyInstances],[RPL_INSTANCE_NONEXISTENT,GservError.Code.InstanceNonExistent],[RPL_INSTANCE_NOT_ALLOWED,GservError.Code.InstanceNotAllowed],[RPL_INSTANCE_ALREADY_STARTED,GservError.Code.InstanceAlreadyStarted],[RPL_INSTANCE_VERS_MISMATCH,GservError.Code.InstanceVersMismatch]]);class GservConnection{get onError(){return this.con.onError}get onClose(){return this.con.onClose}get onLoadInfo(){return this._onLoadInfo.asEvent()}get onGameStart(){return this._onGameStart.asEvent()}get onGameActions(){return this._onGameActions.asEvent()}get onGameDesync(){return this._onGameDesync.asEvent()}get onRateChange(){return this._onRateChange.asEvent()}get onChatMessage(){return this._onChatMessage.asEvent()}get onTaunt(){return this._onTaunt.asEvent()}get onPlayerDisconnect(){return this._onPlayerDisconnect.asEvent()}get onPrivMsgNotAllowed(){return this._onPrivMsgNotAllowed.asEvent()}static factory(e){return new this(new IrcConnection({mode:"text",binaryRplPrefix:RPL_BIN_PREFIX,binaryReqPrefix:REQ_BIN_PREFIX,logFilter:e=>e.replace(/^(user [^ ]+) ([^ ]+)/i,"$1 <redacted>").replace(/^((:.+!.+@.+)?privmsg ([^ ]+ )+):(.+)\r?\n?$/i,"$1:<redacted>")},e))}constructor(e){this._onLoadInfo=new EventDispatcher,this._onGameStart=new EventDispatcher,this._onGameActions=new EventDispatcher,this._onGameDesync=new EventDispatcher,this._onRateChange=new EventDispatcher,this._onChatMessage=new EventDispatcher,this._onTaunt=new EventDispatcher,this._onPlayerDisconnect=new EventDispatcher,this._onPrivMsgNotAllowed=new EventDispatcher,this.handleMessage=t=>{if("string"==typeof t){let e=t.split(" ");var i,r;"ping"===e[0]?this.isOpen()&&this.con.sendMessage("pong"+(e[1]?" "+e[1]:"")):"privmsg"===e[1].toLowerCase()?this.handlePrivMsg(t):e[1]===""+RPL_LOAD_INFO?this.handleLoadInfo(e[3]):e[1]===""+RPL_GAME_START?this.handleGameStart():e[1]===""+RPL_GAME_DESYNC?this._onGameDesync.dispatch(this):e[1]===""+RPL_NET_RATE?([i,r]=e[3].slice(1).split(","),this._onRateChange.dispatch(this,{rate:Number(i),turnNo:Number(r)})):e[1]===""+RPL_TAUNT?this._onTaunt.dispatch(this,{from:e[0].replace(/^:/,""),tauntNo:Number(e[3].replace(/^:/,""))}):e[1]===""+RPL_PLAYER_DISCONNECT?this._onPlayerDisconnect.dispatch(this,e[3].replace(/^:/,"")):e[1]===""+RPL_PRIVMSG_NOT_ALLOWED&&this._onPrivMsgNotAllowed.dispatch(this)}else t[0]===RPL_BIN_GAME_ACTIONS&&this.handlePlayerActions(t.slice(1))},this.con=e}getCurrentUser(){return this.currentUser}getServerName(){return this.serverName}async connect(e,t){return this.con.onMessage.subscribe(this.handleMessage),await this.con.connect(e,t)}close(){this.con.onMessage.unsubscribe(this.handleMessage),this.con.close(),this.currentUser=void 0}isOpen(){return this.con.isOpen()}async cvers(e){let t=await this.con.sendCommand(`cvers ${e} `+API_VERSION,{replyCodes:[RPL_CVERS_OK,RPL_CVERS_OUTDATED]});if(t[0].code===RPL_CVERS_OUTDATED){e=t[0].params?t[0].params.splice(1).join(" ").replace(/^:/,""):"unknown";throw new GservError("Cvers error: "+e,GservError.Code.OutdatedClient)}}async login(e,t){let i=await this.con.sendCommand(`user ${e} `+Base64.encode(t),{replyCodes:[RPL_LOGGED_IN,RPL_BAD_LOGIN,RPL_TOO_MANY_LOGIN_ATTEMPTS,RPL_ALREADY_LOGGED_IN],timeout:10});if(i[0].code!==RPL_LOGGED_IN){var r=gservErrorCodeMap.get(i[0].code)??GservError.Code.Unknown,t=i[0].params?i[0].params.splice(1).join(" ").replace(/^:/,""):"unknown";throw new GservError("Login error: "+t,r)}this.currentUser=e,this.serverName=i[0].raw.match(/^:([^\s]+)/)?.[1]||""}async createGame(e,t,i,r,s,a=!1){if(i.includes(" "))throw new Error("Game opts string cannot include spaces");let n=await this.con.sendCommand(`create ${e} ${t} ${i} ${r} ${s} `+Number(a),{replyCodes:[RPL_INSTANCE_CREATED,RPL_INSTANCE_EXISTS,RPL_INSTANCE_TOO_MANY,RPL_INSTANCE_NOT_ALLOWED]});if(n[0].code!==RPL_INSTANCE_CREATED){s=gservErrorCodeMap.get(n[0].code)??GservError.Code.Unknown,a=n[0].params?n[0].params.splice(1).join(" ").replace(/^:/,""):"unknown";throw new GservError("Create error: "+a,s)}}async joinGame(e,t,i){let r=await this.con.sendCommand(`join ${e} ${t} `+i,{replyCodes:[RPL_INSTANCE_CONNECTED,RPL_INSTANCE_NONEXISTENT,RPL_INSTANCE_NOT_ALLOWED,RPL_INSTANCE_ALREADY_STARTED,RPL_INSTANCE_VERS_MISMATCH]});if(r[0].code!==RPL_INSTANCE_CONNECTED){t=gservErrorCodeMap.get(r[0].code)??GservError.Code.Unknown,i=r[0].params?r[0].params.splice(1).join(" ").replace(/^:/,""):"unknown";throw new GservError("Join error: "+i,t)}}async gameOpts(){let e=await this.con.sendCommand("gameopts",{replyCodes:[RPL_GAME_OPTS]});if(!e[0].params)throw new Error("Unexpected server reply for getopts command. Missing params.");return e[0].params.splice(1).join(" ").replace(/^:/,"")}sendLoadedPercent(e){this.con.sendMessage("loaded "+e)}requestLoadInfo(){this.con.sendMessage("loadinfo")}sendGameStateHash(e,t){let i=new DataStream(10);i.dynamicSize=!1,i.writeUint8(REQ_BIN_PREFIX),i.writeUint8(REQ_BIN_GAME_STATE_HASH),i.writeUint32(e),i.writeUint32(t),this.con.sendMessage(i.toUint8Array())}sendPlayerActive(e){this.con.sendMessage("active "+(e?1:0))}sendTaunt(e){this.con.sendMessage("taunt "+e)}async ping(e){return await this.con.ping(e)}sendPlayerActions(e,t){let i=new DataStream(6);i.writeUint8(REQ_BIN_PREFIX),i.writeUint8(REQ_BIN_GAME_ACTIONS),i.writeUint32(e),i.writeUint8Array(t),this.con.sendMessage(i.toUint8Array())}sendMap(e){let t=new DataStream(2);t.writeUint8(REQ_BIN_PREFIX),t.writeUint8(REQ_BIN_PUT_MAP),t.writeUint8Array((new Serializer).serializeMapData(e)),this.con.sendMessage(t.toUint8Array())}async getMap(){let e=new DataStream(2);e.dynamicSize=!1,e.writeUint8(REQ_BIN_PREFIX),e.writeUint8(REQ_BIN_GET_MAP);var t=await this.con.sendBinCommand(e.toUint8Array(),{replyCodes:[RPL_BIN_MAP_DATA],timeout:15});return(new Parser).parseMapData(t.data)}handleLoadInfo(e){this._onLoadInfo.dispatch(this,e.replace(/^:/,""))}handleGameStart(){this._onGameStart.dispatch(this,void 0)}handlePlayerActions(e){this._onGameActions.dispatch(this,e)}sayChannel(e){this.privmsg([RECIPIENT_ALL],e)}privmsg(e,t){if(!this.currentUser)throw new Error("Must login before sending messages");t.length&&(e=e.join(","),this.con.sendMessage(`privmsg ${e} :`+t))}handlePrivMsg(e){var t=e.match(/^:([A-Za-z0-9-_]+) PRIVMSG ([A-Za-z0-9-_#']+) :(.*)/i);if(!t)throw new Error(`Unexpected PRIVMSG message format "${e}"`);var[,i,r,e]=t;let s;t=new Date;r===RECIPIENT_ALL?s={from:i,to:{type:ChatRecipientType.Channel,name:r},text:e,time:t}:r===this.currentUser&&(s={from:i,to:i===this.getServerName()?{type:ChatRecipientType.Page,name:r}:{type:ChatRecipientType.Channel,name:RECIPIENT_TEAM},text:e,time:t}),s&&this._onChatMessage.dispatch(this,s)}}const computeNetworkTurnMillis=(e,t)=>{return Math.max(1,Math.ceil(e/t))*t};class LockstepManager{get onLagStateChange(){return this._onLagStateChange.asEvent()}get onActionsSent(){return this._onActionsSent.asEvent()}get onActionsProcessed(){return this._onActionsProcessed.asEvent()}get onActionsReceived(){return this._onActionsReceived.asEvent()}constructor(e,t,i,r,s,a,n,o,l,h,c,d,u){this.game=e,this.gservCon=t,this.gameoptParser=i,this.gameoptSerializer=r,this.actionSerializer=s,this.actionFactory=a,this.inputActions=n,this.onDesync=o,this.actionLogger=l,this.netLogger=h,this.debugLogger=c,this.replayRecorder=d,this.debugGameState=u,this.debugGameStateHistory=[],this.queuedRateChanges=[],this.errorState=!1,this.passiveMode=!1,this.receivedActions=new Map,this.receivedNetworkTurn=0,this.lagState=!1,this._onLagStateChange=new EventDispatcher,this._onActionsSent=new EventDispatcher,this._onActionsProcessed=new EventDispatcher,this._onActionsReceived=new EventDispatcher,this.receiveActions=e=>{let t=new DataStream(e);var i=t.readUint32(),e=this.gameoptParser.parseAllPlayerActions(t);this.receivedNetworkTurn=i,this.receivedActions.set(i,e),this._onActionsReceived.dispatch(void 0,i)},this.handleGameDesync=()=>{this.setErrorState(),this.onDesync()}}init(){this.gameTurnMillis=1e3/(this.game.desiredSpeed.value*GameSpeed.BASE_TICKS_PER_SECOND),this.currentNetworkTurn=0,this.currentSubTurn=0,this.gservCon.onGameActions.subscribe(this.receiveActions),this.gservCon.onGameDesync.subscribe(this.handleGameDesync),this.debug("Init: gameTurnMillis = "+this.gameTurnMillis)}canAdvanceNetworkTurn(){return this.currentNetworkTurn<2||this.receivedActions.has(this.currentNetworkTurn-2)}setErrorState(){this.errorState=!0}getErrorState(){return this.errorState}setRate(e){if(this.debug(`Recv rate: ${e.rate} (turn ${e.turnNo})`),0===this.currentSubTurn&&0===this.currentNetworkTurn&&0===e.turnNo)this.updateRate(e.rate);else{if(e.turnNo<this.currentNetworkTurn-2)throw new Error("Rate change has turn number more than two turns in the past.");this.queuedRateChanges.push(e)}}updateRate(e){this.networkTurnMillis=computeNetworkTurnMillis(e,this.gameTurnMillis),this.hashCheckTurnInterval=Math.ceil(LockstepManager.PREFERRED_HASH_CHECK_MILLIS/this.networkTurnMillis),this.netLogger?.debug(`Rate set to ${e} (${this.networkTurnMillis}ms) @ `+this.currentNetworkTurn)}setPassiveMode(e){this.debug("Send passive: "+e),this.passiveMode=e,this.gservCon.sendPlayerActive(!e)}getTurnMillis(){return this.gameTurnMillis}doGameTurn(e){if(!this.errorState){if(!this.networkTurnMillis)throw new Error("Network turn rate should be set by now.");if(this.game.status!==GameStatus.Ended){if(0===this.currentSubTurn){var t=this.queuedRateChanges[0];if(t&&t.turnNo+2===this.currentNetworkTurn&&(this.debug(`Process rate ${t.rate} (turn ${t.turnNo})`),this.updateRate(t.rate),this.queuedRateChanges.shift()),!this.canAdvanceNetworkTurn())return this.handleCommsLag(!0,e),this.debug("Lag state: "+this.lagState),!1;this.debug("Advance turn"),this.commsLagStartTime&&0<e-this.commsLagStartTime&&this.netLogger?.debug(`Waited ${Math.round(e-this.commsLagStartTime)}ms `+"for other clients to catch up."),this.handleCommsLag(!1,e),!this.passiveMode&&this.currentNetworkTurn>=this.receivedNetworkTurn&&this.sendActions(),2<=this.currentNetworkTurn&&(i=this.receivedActions.get(this.currentNetworkTurn-2),this.replayRecorder.recordActions(this.game.currentTick,i),this.processActions(i),this.receivedActions.delete(this.currentNetworkTurn-2),this._onActionsProcessed.dispatch(void 0,this.currentNetworkTurn-2)),this.game.update(),this.passiveMode||this.currentNetworkTurn%this.hashCheckTurnInterval!=0||this.gservCon.sendGameStateHash(this.currentNetworkTurn,this.game.getHash()),this.networkTurnMillis>this.gameTurnMillis?this.currentSubTurn++:this.currentNetworkTurn++}else this.debug("Update"),this.game.update(),this.currentSubTurn++,this.currentSubTurn>=this.networkTurnMillis/this.gameTurnMillis&&(this.currentSubTurn=0,this.currentNetworkTurn++);var i;this.debugGameState&&(i=this.networkTurnMillis/this.gameTurnMillis*this.hashCheckTurnInterval,this.debugGameStateHistory.length>i&&this.debugGameStateHistory.shift(),this.debugGameStateHistory.push(this.game.debugGetState()))}else this.game.update()}}handleCommsLag(e,t){e?(this.commsLagStartTime||(this.commsLagStartTime=t),t-this.commsLagStartTime>LAG_STATE_THRESH_MILLIS&&this.updateLagState(!0)):(this.commsLagStartTime=void 0,this.updateLagState(!1))}updateLagState(e){e!==this.lagState&&(this.lagState=e,this._onLagStateChange.dispatch(void 0,e))}sendActions(){let e=this.inputActions.dequeueAll();e.length||e.push(new NoAction);var t=this.gameoptSerializer.serializePlayerActions(e.map(e=>this.actionSerializer.getActionPayload(e)));this.debug("Send actions: "+t),this.gservCon.sendPlayerActions(this.currentNetworkTurn,t),this._onActionsSent.dispatch(void 0,this.currentNetworkTurn)}processActions(e){[...e].forEach(([i,e])=>e.forEach(e=>{let t=this.actionFactory.create(e.id);t.player=this.game.getPlayer(i),t.unserialize(e.params),t.process();e=t.print();e&&this.actionLogger?.debug(`(${t.player.name})@${this.game.currentTick}: `+e)}))}debug(e){this.debugLogger?.(`${this.currentNetworkTurn}-${this.currentSubTurn}-${this.game.currentTick}: `+e)}dispose(){this.setErrorState(),this.gservCon.onGameActions.unsubscribe(this.receiveActions),this.gservCon.onGameDesync.unsubscribe(this.handleGameDesync)}}LockstepManager.PREFERRED_HASH_CHECK_MILLIS=1e3;const external_perf_hooks_namespaceObject=__WEBPACK_EXTERNAL_createRequire_require("perf_hooks");class AiAnimationLoop{constructor(e){this.gameTurnMgr=e,this.isStarted=!1}start(){this.isStarted||(this.isStarted=!0,this.startTime=void 0,this.lastGameFrame=0)}async waitForTick(){return new Promise((e,t)=>this.doWaitForTick(e,t))}doWaitForTick(e,t){try{this.isStarted||e();var i=external_perf_hooks_namespaceObject.performance.now(),r=this.updateDeltaGameFrames(i);if(0<r)if(!(!1===this.gameTurnMgr.doGameTurn(i)))return void e();setImmediate(()=>this.doWaitForTick(e,t))}catch(e){t(e)}}updateDeltaGameFrames(e){var t=this.gameTurnMgr.getTurnMillis(),i=t!==this.lastGameTurnMillis;this.lastGameTurnMillis=t,i&&(this.lastGameFrame=0,this.startTime=e);let r=0;return this.startTime?(i=e-this.startTime,t=Math.round(i/t),r=t-this.lastGameFrame,this.lastGameFrame=t):this.startTime=e,r}stop(){this.isStarted&&(this.isStarted=!1)}destroy(){this.stop()}}const external_fs_namespaceObject=__WEBPACK_EXTERNAL_createRequire_require("fs");var _GameInstanceApi_bots,_GameInstanceApi_game,_GameInstanceApi_gameApi,_GameInstanceApi_eventsApi,_GameInstanceApi_replay,_GameInstanceApi_turnMgr,_GameInstanceApi_aiAnimationLoop,_GameInstanceApi_onDispose,GameInstanceApi_classPrivateFieldGet=function(e,t,i,r){if("a"===i&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?r:"a"===i?r.call(e):r?r.value:t.get(e)},GameInstanceApi_classPrivateFieldSet=function(e,t,i,r,s){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!s)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!s:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?s.call(e,i):s?s.value=i:t.set(e,i),i};class GameInstanceApi{get gameApi(){return GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_gameApi,"f")}constructor(e,t,i,r,s,a,n,o,l){_GameInstanceApi_bots.set(this,void 0),_GameInstanceApi_game.set(this,void 0),_GameInstanceApi_gameApi.set(this,void 0),_GameInstanceApi_eventsApi.set(this,void 0),_GameInstanceApi_replay.set(this,void 0),_GameInstanceApi_turnMgr.set(this,void 0),_GameInstanceApi_aiAnimationLoop.set(this,void 0),_GameInstanceApi_onDispose.set(this,void 0),GameInstanceApi_classPrivateFieldSet(this,_GameInstanceApi_bots,e,"f"),GameInstanceApi_classPrivateFieldSet(this,_GameInstanceApi_game,t,"f"),GameInstanceApi_classPrivateFieldSet(this,_GameInstanceApi_gameApi,new GameApi(t,!1),"f"),GameInstanceApi_classPrivateFieldSet(this,_GameInstanceApi_eventsApi,new EventsApi(t.events),"f"),GameInstanceApi_classPrivateFieldSet(this,_GameInstanceApi_replay,i,"f"),GameInstanceApi_classPrivateFieldSet(this,_GameInstanceApi_turnMgr,a,"f"),GameInstanceApi_classPrivateFieldSet(this,_GameInstanceApi_aiAnimationLoop,o,"f"),GameInstanceApi_classPrivateFieldSet(this,_GameInstanceApi_onDispose,l,"f"),GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_eventsApi,"f").subscribe(t=>e.forEach(e=>e.onGameEvent(t,GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_gameApi,"f")))),e.forEach(e=>{e.setContext(new BotContext(GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_gameApi,"f"),new PlayerApi(e.name,GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_gameApi,"f"),new ActionsApi(t,r,s,e,n),new ProductionApi(t.getPlayerByName(e.name).production)),new LoggerApi(AppLogger.get(e.name),GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_gameApi,"f")))),e.onGameInit(GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_gameApi,"f")),e.onGameStart(GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_gameApi,"f"))})}isFinished(){return GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_game,"f").status===GameStatus.Ended||GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_turnMgr,"f").getErrorState()}async update(){if(GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_aiAnimationLoop,"f"))await GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_aiAnimationLoop,"f").waitForTick();else{if(!(GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_turnMgr,"f")instanceof AiPlayTurnManager))throw new Error("Missing animation loop or turn manager");GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_turnMgr,"f").doGameTurn()}GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_bots,"f").forEach(e=>e.onGameTick(GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_gameApi,"f")))}getCurrentTick(){return GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_gameApi,"f").getCurrentTick()}getTickRate(){return GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_gameApi,"f").getTickRate()}getPlayerStats(){return GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_game,"f").getNonNeutralPlayers().filter(e=>!e.isObserver).map(t=>({name:t.name,country:t.country,ai:t.isAi||GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_bots,"f").some(e=>e.name===t.name),defeated:t.defeated,credits:t.credits,startLocation:t.startLocation}))}saveReplay(e){let t=GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_replay,"f");t.finish(GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_game,"f").currentTick);var i=GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_game,"f").gameOpts.mapName+"_"+Date.now()+Replay.extension,r=t.serialize(),i=external_path_namespaceObject.resolve(e??process.cwd(),i);return external_fs_namespaceObject.writeFileSync(i,r,"utf-8"),process.stdout.write(`Replay saved to "${i}"
3
3
  `),i}getDebugStateDump(){return GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_turnMgr,"f")instanceof LockstepManager?GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_turnMgr,"f").debugGameStateHistory:void 0}dispose(){GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_eventsApi,"f").dispose(),GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_bots,"f").length=0,GameInstanceApi_classPrivateFieldGet(this,_GameInstanceApi_onDispose,"f")?.call(this)}}_GameInstanceApi_bots=new WeakMap,_GameInstanceApi_game=new WeakMap,_GameInstanceApi_gameApi=new WeakMap,_GameInstanceApi_eventsApi=new WeakMap,_GameInstanceApi_replay=new WeakMap,_GameInstanceApi_turnMgr=new WeakMap,_GameInstanceApi_aiAnimationLoop=new WeakMap,_GameInstanceApi_onDispose=new WeakMap;class MixinRules{static getTypes(e){let t=[];return e.noDogEngiKills&&t.push(MixinRulesType.NoDogEngiKills),t}}class MapDigest{static compute(e){return Crc32.calculateCrc(e.getBytes()).toString(16)}}class OnlineBotChatApi{constructor(e,t,i){this.game=e,this.replayRecorder=t,this.gservCon=i,this.disposables=new CompositeDisposable,this.handleGservMessage=e=>{e.to.type===ChatRecipientType.Channel&&e.to.name===RECIPIENT_ALL&&this.replayRecorder.recordChatMessage(this.game.currentTick,e.from,e.text)}}init(){this.gservCon.onChatMessage.subscribe(this.handleGservMessage),this.disposables.add(()=>this.gservCon.onChatMessage.unsubscribe(this.handleGservMessage))}sayAll(e,t){this.gservCon.isOpen()?this.gservCon.sayChannel(t):console.warn("Can't send chat message. Network connection is already closed.")}dispose(){this.disposables.dispose()}}class OfflineBotChatApi{constructor(e,t){this.game=e,this.replayRecorder=t}sayAll(e,t){this.replayRecorder.recordChatMessage(this.game.currentTick,e,t)}}class RouteHelper{static getGameRoute(e){return"#/game/"+Base64.encode(JSON.stringify({gameId:e.gameId,gameTimestamp:e.gameTimestamp,gservUrl:e.gservUrl,playerName:e.playerName,gameOpts:e.gameOpts,tournament:e.tournament}))}static extractGameParams(e){return JSON.parse(Base64.decode(e))}}RouteHelper.modQueryStringName="mod";var PublicApi_classPrivateFieldGet=function(e,t,i,r){if("a"===i&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?r:"a"===i?r.call(e):r?r.value:t.get(e)},PublicApi_classPrivateFieldSet=function(e,t,i,r,s){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!s)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!s:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?s.call(e,i):s?s.value=i:t.set(e,i),i};const resDir=external_path_namespaceObject.resolve((0,external_es_dirname_namespaceObject.default)(),"./res");class PublicApi{constructor(){_PublicApi_instances.add(this),_PublicApi_gameModes.set(this,void 0),_PublicApi_iniLogger.set(this,void 0),_PublicApi_actionLogger.set(this,void 0),_PublicApi_netLogger.set(this,void 0),_PublicApi_isInitialized.set(this,!1),_PublicApi_mapList.set(this,void 0)}async init(e){PublicApi_classPrivateFieldGet(this,_PublicApi_instances,"m",_PublicApi_initLogging).call(this),globalThis.Blob||(globalThis.Blob=(await Promise.resolve().then(__webpack_require__.bind(__webpack_require__,422))).Blob);var t=await(0,external_file_system_access_namespaceObject.getOriginPrivateDirectory)(node_js_namespaceObject.default,external_path_namespaceObject.resolve(e)),i=await(0,external_file_system_access_namespaceObject.getOriginPrivateDirectory)(node_js_namespaceObject.default,resDir),e=await(0,external_file_system_access_namespaceObject.getOriginPrivateDirectory)(node_js_namespaceObject.default,process.cwd());Engine.setActiveEngine(EngineType.RedAlert2),Engine.initGameResSource(GameResSource.Local);let r=await Engine.initRfs(t);r.addDirectoryHandle(i),r.addDirectoryHandle(e);let s=await Engine.initVfs(r,AppLogger.get("vfs"));await s.loadStandaloneFiles(),await s.loadExtraMixFiles(Engine.getActiveEngine()),await s.addMixFile("ra2cd.mix"),await s.loadImplicitMixFiles(Engine.getActiveEngine()),Engine.loadRules(),PublicApi_classPrivateFieldSet(this,_PublicApi_mapList,await Engine.loadMapList(),"f"),PublicApi_classPrivateFieldSet(this,_PublicApi_gameModes,Engine.getMpModes(),"f"),PublicApi_classPrivateFieldSet(this,_PublicApi_isInitialized,!0,"f")}getAvailableMaps(){if(!PublicApi_classPrivateFieldGet(this,_PublicApi_isInitialized,"f"))throw new Error("API is not initialized. Call init() first.");return PublicApi_classPrivateFieldGet(this,_PublicApi_mapList,"f").getAll().map(e=>e.fileName.toLowerCase())}getAvailableGameModes(e){if(!PublicApi_classPrivateFieldGet(this,_PublicApi_isInitialized,"f"))throw new Error("API is not initialized. Call init() first.");let t=PublicApi_classPrivateFieldGet(this,_PublicApi_mapList,"f").getByName(e);if(!t)throw new Error(`Map "${e}" is not available`);return t.gameModes.map(e=>e.id)}async createGame(e){return e.online?await PublicApi_classPrivateFieldGet(this,_PublicApi_instances,"m",_PublicApi_createOnlineGame).call(this,e):await PublicApi_classPrivateFieldGet(this,_PublicApi_instances,"m",_PublicApi_createOfflineGame).call(this,e)}}var _PublicApi_gameModes=new WeakMap,_PublicApi_iniLogger=new WeakMap,_PublicApi_actionLogger=new WeakMap,_PublicApi_netLogger=new WeakMap,_PublicApi_isInitialized=new WeakMap,_PublicApi_mapList=new WeakMap,_PublicApi_instances=new WeakSet,_PublicApi_initLogging=function(){AppLogger.useDefaults(),AppLogger.setLevel(AppLogger.ERROR);const e=process.env.DEBUG_LOGGING;var t;if(e)if(isNaN(e))for(t of e.split(","))AppLogger.get(t).setLevel(AppLogger.DEBUG);else AppLogger.setLevel(Number(e)?AppLogger.DEBUG:AppLogger.ERROR);PublicApi_classPrivateFieldSet(this,_PublicApi_iniLogger,AppLogger.get("ini"),"f"),PublicApi_classPrivateFieldSet(this,_PublicApi_actionLogger,AppLogger.get("action"),"f"),PublicApi_classPrivateFieldSet(this,_PublicApi_netLogger,AppLogger.get("net"),"f")},_PublicApi_createOfflineGame=async function(e){if(!PublicApi_classPrivateFieldGet(this,_PublicApi_isInitialized,"f"))throw new Error("API is not initialized. Call init() first.");if(e.agents.some(e=>!(e instanceof Bot)))throw new Error("All players in the agents array must be bots in offline mode");var t=await PublicApi_classPrivateFieldGet(this,_PublicApi_instances,"m",_PublicApi_generateGameOpts).call(this,e),i=e.agents.filter(e=>e instanceof Bot),r=new MapFile(await Engine.vfs.openFileWithRfs(t.mapName)),s=Math.floor(Date.now()/1e3),a=await PublicApi_classPrivateFieldGet(this,_PublicApi_instances,"m",_PublicApi_initializeGame).call(this,"0",s,t,r,void 0),e=new ActionQueue,s=new ActionFactory;(new ActionFactoryReg).register(s,a,void 0);let n=new Replay;n.init(a.id,a.startTimestamp,t,Engine.getVersion(),Engine.getModHash());r=new ActionSerializer,t=new ReplayRecorder(n,0,a.gameOpts.humanPlayers,r);let o=new AiPlayTurnManager(a,e,t,r,s,PublicApi_classPrivateFieldGet(this,_PublicApi_actionLogger,"f"));o.init();t=new OfflineBotChatApi(a,t);return new GameInstanceApi(i,a,n,s,e,o,t)},_PublicApi_createOnlineGame=async function(e){if(!PublicApi_classPrivateFieldGet(this,_PublicApi_isInitialized,"f"))throw new Error("API is not initialized. Call init() first.");if(!e.serverUrl)throw new Error("Must specify a serverUrl");if(!e.clientUrl)throw new Error("Must specify a clientUrl");let t=[];for(var i of e.agents){if(!i.name.match(/^[a-z0-9-_]+$/i))throw new Error(`Agent name "${i.name}" must contain only alphanumeric characters, dash (-) or underscore (_)`);i instanceof Bot&&t.push(i)}if(!(e.agents[0]instanceof Bot))throw new Error("The first object in the agents array must be a Bot instance in online mode");if(e.agents.slice(1).some(e=>e instanceof Bot))throw new Error("Only the first player in the agents array can be a bot in online mode");var r=await PublicApi_classPrivateFieldGet(this,_PublicApi_instances,"m",_PublicApi_generateGameOpts).call(this,e);let s=GservConnection.factory(PublicApi_classPrivateFieldGet(this,_PublicApi_netLogger,"f"));await s.connect(e.serverUrl),await s.cvers(Engine.getVersion()),await s.login(e.agents[0].name,e.botPassword);let a=new Serializer;var n,o=a.serializeOptions(r),l=external_node_crypto_namespaceObject.randomUUID(),h=Math.floor(Date.now()/1e3);process.stdout.write(`
4
4
  You may use the following link(s) to join, after the game is created:
5
5
 
6
- `);let c=new Map;for(n of e.agents.slice(1)){var u=e.clientUrl.replace(/\/$/,"")+("/"+RouteHelper.getGameRoute({gameId:l,gameTimestamp:h,gservUrl:e.serverUrl,playerName:n.name}));c.set(n,u),process.stdout.write(u+"\n")}e.nonInteractive||(process.stdout.write(`
6
+ `);let c=new Map;for(n of e.agents.slice(1)){var d=e.clientUrl.replace(/\/$/,"")+("/"+RouteHelper.getGameRoute({gameId:l,gameTimestamp:h,gservUrl:e.serverUrl,playerName:n.name}));c.set(n,d),process.stdout.write(d+"\n")}e.nonInteractive||(process.stdout.write(`
7
7
 
8
8
  Press ENTER to create the game now...
9
9
  `),await new Promise(e=>process.stdin.once("data",e)),process.stdin.pause()),process.stdout.write(`Creating game...
10
- `),await s.createGame(l,h,o,Engine.getVersion(),Engine.getModHash());let d=new Parser;var p=d.parseOptions(await s.gameOpts());let g=await Engine.vfs.openFileWithRfs(r.mapName);var m=new MapFile(g);r.mapOfficial||s.sendMap(g.readAsString());var y=e.agents[0].name;let T=await PublicApi_classPrivateFieldGet(this,_PublicApi_instances,"m",_PublicApi_initializeGame).call(this,l,h,p,m,y);o=new ActionSerializer,r=new ActionQueue,m=new ActionFactory;(new ActionFactoryReg).register(m,T,y);let f=new Replay;f.init(T.id,T.startTimestamp,p,Engine.getVersion(),Engine.getModHash());p=new ReplayRecorder(f,0,T.gameOpts.humanPlayers,o);let v=new LockstepManager(T,s,d,a,o,m,r,()=>{console.error("Desync detected."),process.exit(1)},PublicApi_classPrivateFieldGet(this,_PublicApi_actionLogger,"f"),void 0,void 0,p,e.debugStateDumps??!1);v.init();let b=new AiAnimationLoop(v);s.onRateChange.subscribe(e=>v.setRate(e)),T.onEnd.subscribe(()=>{process.stdout.write(`Game ended.
10
+ `),await s.createGame(l,h,o,Engine.getVersion(),Engine.getModHash());let u=new Parser;var p=u.parseOptions(await s.gameOpts());let g=await Engine.vfs.openFileWithRfs(r.mapName);var m=new MapFile(g);r.mapOfficial||s.sendMap(g.readAsString());var y=e.agents[0].name;let T=await PublicApi_classPrivateFieldGet(this,_PublicApi_instances,"m",_PublicApi_initializeGame).call(this,l,h,p,m,y);o=new ActionSerializer,r=new ActionQueue,m=new ActionFactory;(new ActionFactoryReg).register(m,T,y);let f=new Replay;f.init(T.id,T.startTimestamp,p,Engine.getVersion(),Engine.getModHash());p=new ReplayRecorder(f,0,T.gameOpts.humanPlayers,o);let v=new LockstepManager(T,s,u,a,o,m,r,()=>{console.error("Desync detected."),process.exit(1)},PublicApi_classPrivateFieldGet(this,_PublicApi_actionLogger,"f"),void 0,void 0,p,e.debugStateDumps??!1);v.init();let b=new AiAnimationLoop(v);s.onRateChange.subscribe(e=>v.setRate(e)),T.onEnd.subscribe(()=>{process.stdout.write(`Game ended.
11
11
  `),b.destroy()}),process.stdout.write(`
12
12
  Game created.`),process.stdout.write(`
13
13
  Waiting for players to join...