@astefanski/storm-parser 0.0.14 → 0.0.15
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.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -3
- package/dist/index.mjs +3 -3
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -627,6 +627,7 @@ declare class LiveStreamParser extends ReplayParser {
|
|
|
627
627
|
constructor(build?: number);
|
|
628
628
|
parseTracker(buffer: Buffer): ReplayEvent[];
|
|
629
629
|
parseGame(buffer: Buffer): ReplayEvent[];
|
|
630
|
+
parseDetails(buffer: Buffer): DecodedData | null;
|
|
630
631
|
}
|
|
631
632
|
|
|
632
633
|
declare class ReplayAnalyzer {
|
package/dist/index.d.ts
CHANGED
|
@@ -627,6 +627,7 @@ declare class LiveStreamParser extends ReplayParser {
|
|
|
627
627
|
constructor(build?: number);
|
|
628
628
|
parseTracker(buffer: Buffer): ReplayEvent[];
|
|
629
629
|
parseGame(buffer: Buffer): ReplayEvent[];
|
|
630
|
+
parseDetails(buffer: Buffer): DecodedData | null;
|
|
630
631
|
}
|
|
631
632
|
|
|
632
633
|
declare class ReplayAnalyzer {
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";var Fe=Object.create;var Y=Object.defineProperty;var Xe=Object.getOwnPropertyDescriptor;var Ge=Object.getOwnPropertyNames;var Ke=Object.getPrototypeOf,je=Object.prototype.hasOwnProperty;var K=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),Qe=(t,e)=>{for(var r in e)Y(t,r,{get:e[r],enumerable:!0})},pe=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Ge(e))!je.call(t,i)&&i!==r&&Y(t,i,{get:()=>e[i],enumerable:!(n=Xe(e,i))||n.enumerable});return t};var J=(t,e,r)=>(r=t!=null?Fe(Ke(t)):{},pe(e||!t||!t.__esModule?Y(r,"default",{value:t,enumerable:!0}):r,t)),Ve=t=>pe(Y({},"__esModule",{value:!0}),t);var _e=K((Ct,he)=>{"use strict";var be=[0,1,3,7,15,31,63,127,255],j=function(t){this.stream=t,this.bitOffset=0,this.curByte=0,this.hasByte=!1};j.prototype._ensureByte=function(){this.hasByte||(this.curByte=this.stream.readByte(),this.hasByte=!0)};j.prototype.read=function(t){for(var e=0;t>0;){this._ensureByte();var r=8-this.bitOffset;if(t>=r)e<<=r,e|=be[r]&this.curByte,this.hasByte=!1,this.bitOffset=0,t-=r;else{e<<=t;var n=r-t;e|=(this.curByte&be[t]<<n)>>n,this.bitOffset+=t,t=0}}return e};j.prototype.seek=function(t){var e=t%8,r=(t-e)/8;this.bitOffset=e,this.stream.seek(r),this.hasByte=!1};j.prototype.pi=function(){var t=new Buffer(6),e;for(e=0;e<t.length;e++)t[e]=this.read(8);return t.toString("hex")};he.exports=j});var ye=K((It,ge)=>{"use strict";var O=function(){};O.prototype.readByte=function(){throw new Error("abstract method readByte() not implemented")};O.prototype.read=function(t,e,r){for(var n=0;n<r;){var i=this.readByte();if(i<0)return n===0?-1:n;t[e++]=i,n++}return n};O.prototype.seek=function(t){throw new Error("abstract method seek() not implemented")};O.prototype.writeByte=function(t){throw new Error("abstract method readByte() not implemented")};O.prototype.write=function(t,e,r){var n;for(n=0;n<r;n++)this.writeByte(t[e++]);return r};O.prototype.flush=function(){};ge.exports=O});var ve=K((At,xe)=>{"use strict";xe.exports=(function(){var t=new Uint32Array([0,79764919,159529838,222504665,319059676,398814059,445009330,507990021,638119352,583659535,797628118,726387553,890018660,835552979,1015980042,944750013,1276238704,1221641927,1167319070,1095957929,1595256236,1540665371,1452775106,1381403509,1780037320,1859660671,1671105958,1733955601,2031960084,2111593891,1889500026,1952343757,2552477408,2632100695,2443283854,2506133561,2334638140,2414271883,2191915858,2254759653,3190512472,3135915759,3081330742,3009969537,2905550212,2850959411,2762807018,2691435357,3560074640,3505614887,3719321342,3648080713,3342211916,3287746299,3467911202,3396681109,4063920168,4143685023,4223187782,4286162673,3779000052,3858754371,3904687514,3967668269,881225847,809987520,1023691545,969234094,662832811,591600412,771767749,717299826,311336399,374308984,453813921,533576470,25881363,88864420,134795389,214552010,2023205639,2086057648,1897238633,1976864222,1804852699,1867694188,1645340341,1724971778,1587496639,1516133128,1461550545,1406951526,1302016099,1230646740,1142491917,1087903418,2896545431,2825181984,2770861561,2716262478,3215044683,3143675388,3055782693,3001194130,2326604591,2389456536,2200899649,2280525302,2578013683,2640855108,2418763421,2498394922,3769900519,3832873040,3912640137,3992402750,4088425275,4151408268,4197601365,4277358050,3334271071,3263032808,3476998961,3422541446,3585640067,3514407732,3694837229,3640369242,1762451694,1842216281,1619975040,1682949687,2047383090,2127137669,1938468188,2001449195,1325665622,1271206113,1183200824,1111960463,1543535498,1489069629,1434599652,1363369299,622672798,568075817,748617968,677256519,907627842,853037301,1067152940,995781531,51762726,131386257,177728840,240578815,269590778,349224269,429104020,491947555,4046411278,4126034873,4172115296,4234965207,3794477266,3874110821,3953728444,4016571915,3609705398,3555108353,3735388376,3664026991,3290680682,3236090077,3449943556,3378572211,3174993278,3120533705,3032266256,2961025959,2923101090,2868635157,2813903052,2742672763,2604032198,2683796849,2461293480,2524268063,2284983834,2364738477,2175806836,2238787779,1569362073,1498123566,1409854455,1355396672,1317987909,1246755826,1192025387,1137557660,2072149281,2135122070,1912620623,1992383480,1753615357,1816598090,1627664531,1707420964,295390185,358241886,404320391,483945776,43990325,106832002,186451547,266083308,932423249,861060070,1041341759,986742920,613929101,542559546,756411363,701822548,3316196985,3244833742,3425377559,3370778784,3601682597,3530312978,3744426955,3689838204,3819031489,3881883254,3928223919,4007849240,4037393693,4100235434,4180117107,4259748804,2310601993,2373574846,2151335527,2231098320,2596047829,2659030626,2470359227,2550115596,2947551409,2876312838,2788305887,2733848168,3165939309,3094707162,3040238851,2985771188]),e=function(){var r=4294967295;this.getCRC=function(){return~r>>>0},this.updateCRC=function(n){r=r<<8^t[(r>>>24^n)&255]},this.updateCRCRun=function(n,i){for(;i-- >0;)r=r<<8^t[(r>>>24^n)&255]}};return e})()});var Te=K((Mt,We)=>{We.exports={name:"seek-bzip",version:"2.0.0",contributors:["C. Scott Ananian (http://cscott.net)","Eli Skeggs","Kevin Kwok","Rob Landley (http://landley.net)"],description:"a pure-JavaScript Node.JS module for random-access decoding bzip2 data",main:"./lib/index.js",repository:{type:"git",url:"https://github.com/cscott/seek-bzip.git"},license:"MIT",bin:{"seek-bunzip":"./bin/seek-bunzip","seek-table":"./bin/seek-bzip-table"},directories:{test:"test"},dependencies:{commander:"^6.0.0"},devDependencies:{fibers:"^5.0.0",mocha:"^8.1.0"},scripts:{test:"mocha"}}});var Be=K((Ht,Re)=>{"use strict";var $e=_e(),Q=ye(),Ee=ve(),Pe=Te(),ee=20,ke=258,Se=0,qe=1,Ze=2,Ye=6,Je=50,et="314159265359",tt="177245385090",we=function(t,e){var r=t[e],n;for(n=e;n>0;n--)t[n]=t[n-1];return t[0]=r,r},g={OK:0,LAST_BLOCK:-1,NOT_BZIP_DATA:-2,UNEXPECTED_INPUT_EOF:-3,UNEXPECTED_OUTPUT_EOF:-4,DATA_ERROR:-5,OUT_OF_MEMORY:-6,OBSOLETE_INPUT:-7,END_OF_BLOCK:-8},I={};I[g.LAST_BLOCK]="Bad file checksum";I[g.NOT_BZIP_DATA]="Not bzip data";I[g.UNEXPECTED_INPUT_EOF]="Unexpected input EOF";I[g.UNEXPECTED_OUTPUT_EOF]="Unexpected output EOF";I[g.DATA_ERROR]="Data error";I[g.OUT_OF_MEMORY]="Out of memory";I[g.OBSOLETE_INPUT]="Obsolete (pre 0.9.5) bzip format not supported.";var T=function(t,e){var r=I[t]||"unknown error";e&&(r+=": "+e);var n=new TypeError(r);throw n.errorCode=t,n},S=function(t,e){this.writePos=this.writeCurrent=this.writeCount=0,this._start_bunzip(t,e)};S.prototype._init_block=function(){var t=this._get_next_block();return t?(this.blockCRC=new Ee,!0):(this.writeCount=-1,!1)};S.prototype._start_bunzip=function(t,e){var r=new Buffer(4);(t.read(r,0,4)!==4||String.fromCharCode(r[0],r[1],r[2])!=="BZh")&&T(g.NOT_BZIP_DATA,"bad magic");var n=r[3]-48;(n<1||n>9)&&T(g.NOT_BZIP_DATA,"level out of range"),this.reader=new $e(t),this.dbufSize=1e5*n,this.nextoutput=0,this.outputStream=e,this.streamCRC=0};S.prototype._get_next_block=function(){var t,e,r,n=this.reader,i=n.pi();if(i===tt)return!1;i!==et&&T(g.NOT_BZIP_DATA),this.targetBlockCRC=n.read(32)>>>0,this.streamCRC=(this.targetBlockCRC^(this.streamCRC<<1|this.streamCRC>>>31))>>>0,n.read(1)&&T(g.OBSOLETE_INPUT);var a=n.read(24);a>this.dbufSize&&T(g.DATA_ERROR,"initial position out of bounds");var s=n.read(16),o=new Buffer(256),c=0;for(t=0;t<16;t++)if(s&1<<15-t){var l=t*16;for(r=n.read(16),e=0;e<16;e++)r&1<<15-e&&(o[c++]=l+e)}var f=n.read(3);(f<Ze||f>Ye)&&T(g.DATA_ERROR);var u=n.read(15);u===0&&T(g.DATA_ERROR);var m=new Buffer(256);for(t=0;t<f;t++)m[t]=t;var b=new Buffer(u);for(t=0;t<u;t++){for(e=0;n.read(1);e++)e>=f&&T(g.DATA_ERROR);b[t]=we(m,e)}var d=c+2,h=[],p;for(e=0;e<f;e++){var _=new Buffer(d),y=new Uint16Array(ee+1);for(s=n.read(5),t=0;t<d;t++){for(;(s<1||s>ee)&&T(g.DATA_ERROR),!!n.read(1);)n.read(1)?s--:s++;_[t]=s}var x,P;for(x=P=_[0],t=1;t<d;t++)_[t]>P?P=_[t]:_[t]<x&&(x=_[t]);p={},h.push(p),p.permute=new Uint16Array(ke),p.limit=new Uint32Array(ee+2),p.base=new Uint32Array(ee+1),p.minLen=x,p.maxLen=P;var H=0;for(t=x;t<=P;t++)for(y[t]=p.limit[t]=0,s=0;s<d;s++)_[s]===t&&(p.permute[H++]=s);for(t=0;t<d;t++)y[_[t]]++;for(H=s=0,t=x;t<P;t++)H+=y[t],p.limit[t]=H-1,H<<=1,s+=y[t],p.base[t+1]=H-s;p.limit[P+1]=Number.MAX_VALUE,p.limit[P]=H+y[P]-1,p.base[x]=0}var N=new Uint32Array(256);for(t=0;t<256;t++)m[t]=t;var L=0,C=0,de=0,E,X=this.dbuf=new Uint32Array(this.dbufSize);for(d=0;;){for(d--||(d=Je-1,de>=u&&T(g.DATA_ERROR),p=h[b[de++]]),t=p.minLen,e=n.read(t);t>p.maxLen&&T(g.DATA_ERROR),!(e<=p.limit[t]);t++)e=e<<1|n.read(1);e-=p.base[t],(e<0||e>=ke)&&T(g.DATA_ERROR);var G=p.permute[e];if(G===Se||G===qe){L||(L=1,s=0),G===Se?s+=L:s+=2*L,L<<=1;continue}if(L)for(L=0,C+s>this.dbufSize&&T(g.DATA_ERROR),E=o[m[0]],N[E]+=s;s--;)X[C++]=E;if(G>c)break;C>=this.dbufSize&&T(g.DATA_ERROR),t=G-1,E=we(m,t),E=o[E],N[E]++,X[C++]=E}for((a<0||a>=C)&&T(g.DATA_ERROR),e=0,t=0;t<256;t++)r=e+N[t],N[t]=e,e=r;for(t=0;t<C;t++)E=X[t]&255,X[N[E]]|=t<<8,N[E]++;var Z=0,ue=0,me=0;return C&&(Z=X[a],ue=Z&255,Z>>=8,me=-1),this.writePos=Z,this.writeCurrent=ue,this.writeCount=C,this.writeRun=me,!0};S.prototype._read_bunzip=function(t,e){var r,n,i;if(this.writeCount<0)return 0;for(var a=0,s=this.dbuf,o=this.writePos,c=this.writeCurrent,l=this.writeCount,f=this.outputsize,u=this.writeRun;l;){for(l--,n=c,o=s[o],c=o&255,o>>=8,u++===3?(r=c,i=n,c=-1):(r=1,i=c),this.blockCRC.updateCRCRun(i,r);r--;)this.outputStream.writeByte(i),this.nextoutput++;c!=n&&(u=0)}return this.writeCount=l,this.blockCRC.getCRC()!==this.targetBlockCRC&&T(g.DATA_ERROR,"Bad block CRC (got "+this.blockCRC.getCRC().toString(16)+" expected "+this.targetBlockCRC.toString(16)+")"),this.nextoutput};var oe=function(t){if("readByte"in t)return t;var e=new Q;return e.pos=0,e.readByte=function(){return t[this.pos++]},e.seek=function(r){this.pos=r},e.eof=function(){return this.pos>=t.length},e},De=function(t){var e=new Q,r=!0;if(t)if(typeof t=="number")e.buffer=new Buffer(t),r=!1;else{if("writeByte"in t)return t;e.buffer=t,r=!1}else e.buffer=new Buffer(16384);return e.pos=0,e.writeByte=function(n){if(r&&this.pos>=this.buffer.length){var i=new Buffer(this.buffer.length*2);this.buffer.copy(i),this.buffer=i}this.buffer[this.pos++]=n},e.getBuffer=function(){if(this.pos!==this.buffer.length){if(!r)throw new TypeError("outputsize does not match decoded input");var n=new Buffer(this.pos);this.buffer.copy(n,0,0,this.pos),this.buffer=n}return this.buffer},e._coerced=!0,e};S.Err=g;S.decode=function(t,e,r){for(var n=oe(t),i=De(e),a=new S(n,i);!("eof"in n&&n.eof());)if(a._init_block())a._read_bunzip();else{var s=a.reader.read(32)>>>0;if(s!==a.streamCRC&&T(g.DATA_ERROR,"Bad stream CRC (got "+a.streamCRC.toString(16)+" expected "+s.toString(16)+")"),r&&"eof"in n&&!n.eof())a._start_bunzip(n,i);else break}if("getBuffer"in i)return i.getBuffer()};S.decodeBlock=function(t,e,r){var n=oe(t),i=De(r),a=new S(n,i);a.reader.seek(e);var s=a._get_next_block();if(s&&(a.blockCRC=new Ee,a.writeCopies=0,a._read_bunzip()),"getBuffer"in i)return i.getBuffer()};S.table=function(t,e,r){var n=new Q;n.delegate=oe(t),n.pos=0,n.readByte=function(){return this.pos++,this.delegate.readByte()},n.delegate.eof&&(n.eof=n.delegate.eof.bind(n.delegate));var i=new Q;i.pos=0,i.writeByte=function(){this.pos++};for(var a=new S(n,i),s=a.dbufSize;!("eof"in n&&n.eof());){var o=n.pos*8+a.reader.bitOffset;if(a.reader.hasByte&&(o-=8),a._init_block()){var c=i.pos;a._read_bunzip(),e(o,i.pos-c)}else{var l=a.reader.read(32);if(r&&"eof"in n&&!n.eof())a._start_bunzip(n,i),console.assert(a.dbufSize===s,"shouldn't change block size within multistream file");else break}}};S.Stream=Q;S.version=Pe.version;S.license=Pe.license;Re.exports=S});var Rt={};Qe(Rt,{LiveStreamParser:()=>ie,ReplayAnalyzer:()=>se,ReplayParser:()=>M});module.exports=Ve(Rt);var Ae=J(require("fs")),V=J(require("zlib")),rt=Be(),Ce=512,nt=65536,it=16777216,at=67108864,st=2147483648,ot={TABLE_OFFSET:0,HASH_A:1,HASH_B:2,TABLE:3};function ct(){let t=1048577,e=new Uint32Array(256*5);for(let r=0;r<256;r++){let n=r;for(let i=0;i<5;i++){t=(t*125+3)%2796203;let a=(t&65535)<<16;t=(t*125+3)%2796203;let s=t&65535;e[n]=(a|s)>>>0,n+=256}}return e}var Ie=ct(),te=class{file;header;hashTable;blockTable;files;constructor(e,r=!0){if(Buffer.isBuffer(e)?this.file=e:this.file=Ae.readFileSync(e),this.header=this.readHeader(),this.hashTable=this.readTable("hash"),this.blockTable=this.readTable("block"),r){let n=this.readFile("(listfile)");n?this.files=n.toString("utf8").trim().split(`\r
|
|
2
|
-
`):this.files=null}else this.files=null}readHeader(){let e=this.file.toString("utf8",0,4),
|
|
3
|
-
Searched: `+t.join(", "))}var ce=new Map,le=null;function Me(){return le||(le=lt()),le}function re(t){if(ce.has(t))return ce.get(t);let e=Me(),r=A.default.join(e,`protocol${t}.json`);if(!F.default.existsSync(r))return null;let n=JSON.parse(F.default.readFileSync(r,"utf-8"));return ce.set(t,n),n}function ne(){let t=Me();return F.default.readdirSync(t).filter(e=>/^protocol\d+\.json$/.test(e)).map(e=>parseInt(e.match(/\d+/)[0],10)).sort((e,r)=>e-r)}var M=class{mpq;header;build=0;protocol;baseProtocol;constructor(e){e&&(this.mpq=new te(e,!1))}init(){let e=re(29406);if(!e)throw new Error("Base protocol29406 not found. Did postinstall run? Try: npx tsx node_modules/@astefanski/storm-parser/scripts/postinstall.ts");this.baseProtocol=e;let r=this.mpq.header.userDataHeader;if(!r||!r.content)throw new Error("Replay does not have a user data header");let n=new D(r.content,this.baseProtocol.typeinfos);this.header=n.instance(this.baseProtocol.replay_header_typeid),this.build=this.header.m_version.m_baseBuild,this.protocol=this.loadProtocolForBuild(this.build)}loadProtocolForBuild(e){let r=re(e);if(!r){let n=ne(),i=n[0];for(let a of n)a<=e&&a>i&&(i=a);r=re(i)}if(!r)throw new Error(`No protocol found for build ${e}`);return r}*decodeEventStream(e,r,n,i){if(!this.protocol)throw new Error("Protocol not loaded");let a=0;for(;!e.done();){let s=e.used_bits(),o=e.instance(this.protocol.svaruint32_typeid),c=Object.keys(o)[0],l=o[c];a+=l;let f=i?e.instance(this.protocol.replay_userid_typeid):void 0,u=Number(e.instance(r)),m=n[u];if(!m)throw new Error(`Unknown eventid(${u})`);let b=m[0],d=m[1],h=e.instance(b);h._event=d,h._eventid=u,h._gameloop=a,i&&(h._userid=f),e.byte_align(),h._bits=e.used_bits()-s,yield h}}getDetails(){if(!this.protocol)throw new Error("Protocol not loaded");let e=this.mpq.readFile("replay.details");return e?new D(e,this.protocol.typeinfos).instance(this.protocol.game_details_typeid):null}getInitData(){if(!this.protocol)throw new Error("Protocol not loaded");let e=this.mpq.readFile("replay.initData");return e?new z(e,this.protocol.typeinfos).instance(this.protocol.replay_initdata_typeid):null}getTrackerEvents(){if(!this.protocol)throw new Error("Protocol not loaded");let e=this.mpq.readFile("replay.tracker.events");if(!e)return[];let r=new D(e,this.protocol.typeinfos);return Array.from(this.decodeEventStream(r,this.protocol.tracker_eventid_typeid,this.protocol.tracker_event_types,!1))}getGameEvents(){if(!this.protocol)throw new Error("Protocol not loaded");let e=this.mpq.readFile("replay.game.events");if(!e)return[];let r=new z(e,this.protocol.typeinfos);return Array.from(this.decodeEventStream(r,this.protocol.game_eventid_typeid,this.protocol.game_event_types,!0))}getAttributeEvents(){if(!this.protocol)throw new Error("Protocol not loaded");let e=this.mpq.readFile("replay.attributes.events");return e?new D(e,this.protocol.typeinfos).instance(this.protocol.replay_attributes_events_typeid):null}extractFile(e){return this.mpq.readFile(e)}getHeader(){return this.header}getBuild(){return this.build}};var ie=class extends M{constructor(e){super();let r=e;if(!r){let n=ne();r=n[n.length-1]}this.protocol=this.loadProtocolForBuild(r)}parseTracker(e){if(!this.protocol)return[];try{let r=new D(e,this.protocol.typeinfos);return Array.from(this.decodeEventStream(r,this.protocol.tracker_eventid_typeid,this.protocol.tracker_event_types,!1))}catch(r){return console.error("[LiveStreamParser] Failed to parse tracker events",r),[]}}parseGame(e){if(!this.protocol)return[];try{let r=new z(e,this.protocol.typeinfos);return Array.from(this.decodeEventStream(r,this.protocol.game_eventid_typeid,this.protocol.game_event_types,!0))}catch(r){return console.error("[LiveStreamParser] Failed to parse game events",r),[]}}};var He=["Abathur","Alarak","Alexstrasza","Ana","Anduin","Anubarak","Artanis","Arthas","Auriel","Azmodan","Blaze","Brightwing","Cassia","Chen","Cho","Chromie","Deathwing","Deckard","Dehaka","Diablo","DVa","ETC","Falstad","Fenix","Gall","Garrosh","Gazlowe","Genji","Greymane","Guldan","Hanzo","Hogger","Illidan","Imperius","Jaina","Johanna","Junkrat","Kaelthas","KelThuzad","Kerrigan","Kharazim","Leoric","LiLi","LiMing","LtMorales","Lunara","Maiev","Malfurion","MalGanis","Malthael","Medivh","Mei","Mephisto","Muradin","Murky","Nazeebo","Nova","Orphea","Probius","Qhira","Ragnaros","Raynor","Rehgar","Rexxar","Samuro","SgtHammer","Sonya","Stitches","Stukov","Sylvanas","Tassadar","TheButcher","TheLostVikings","Thrall","Tracer","Tychus","Tyrael","Tyrande","Uther","Valeera","Valla","Varian","Whitemane","Xul","Yrel","Zagara","Zarya","Zeratul","Zuljin"],Le={FaerieDragon:"Brightwing",Amazon:"Cassia",Barbarian:"Sonya",Crusader:"Johanna",DemonHunter:"Valla",WitchDoctor:"Nazeebo",Monk:"Kharazim",Wizard:"LiMing",Tinker:"Gazlowe",Medic:"LtMorales",L90ETC:"ETC",Butcher:"TheButcher",LostVikings:"TheLostVikings",Necromancer:"Xul",Dryad:"Lunara",Shapeshifter:"Greymane",ChoGall:"Cho"};function q(t){if(!t)return null;if(He.includes(t))return t;if(Le[t])return Le[t];let e=t.replace(/[^a-zA-Z0-9]/g,"").toLowerCase(),r=He.find(n=>n.toLowerCase()===e);return r||null}var Oe={TownCannonTowerL2:"Fort Tower",TownCannonTowerL3:"Keep Tower",TownTownHallL2:"Fort",TownTownHallL3:"Keep",TownMoonwellL2:"Fort Well",TownMoonwellL3:"Keep Well"},ft={MercLanerMeleeKnight:"Bruiser Camp",MercLanerRangedMage:"Bruiser Camp",MercLanerSiegeGiant:"Siege Camp",MercLanerRangedMinion:"Siege Camp"};function B(t){return Buffer.isBuffer(t)?t.toString("utf8"):typeof t=="string"?t:String(t??"")}function v(t,e){if(!t)return;let r=t.find(n=>B(n.m_key)===e);return r!==void 0?r.m_value:void 0}function ae(t,e){if(!t)return;let r=t.find(n=>B(n.m_key)===e);return r!==void 0?B(r.m_value):void 0}function w(t,e){if(!t)return;let r=t.find(n=>B(n.m_key)===e);return r!==void 0?r.m_value:void 0}function fe(t,e){return`${t}-${e}`}function R(t,e){return(t-e)/16}function Ue(t,e,r){let n={playerIDMap:{},loopGameStart:0,loopGameEnd:0,unitIndex:{},heroUnits:{},heroLives:{}};r.bans||(r.bans={0:[],1:[]}),r.levelTimes={0:{},1:{}},r.takedowns=[],r.structures={},r.XPBreakdown=[],r.mercs={captures:[],units:{}},r.objective={0:{count:0,events:[]},1:{count:0,events:[]},type:r.map||""};for(let i of t)switch(n.loopGameEnd=Math.max(n.loopGameEnd,i._gameloop),i._event){case"NNet.Replay.Tracker.SStatGameEvent":dt(i,n,e,r);break;case"NNet.Replay.Tracker.SHeroBannedEvent":if(i.m_hero){let a=B(i.m_hero),s=q(a);if(!s)break;let o=i.m_controllingTeam===2?1:0;if(r.bans&&r.bans[o]){let c=r.bans[o].length+1,l=r.bans[0].length+r.bans[1].length+1;r.bans[o].push({hero:s,order:c,absolute:l})}}break;case"NNet.Replay.Tracker.SUnitBornEvent":pt(i,n,r);break;case"NNet.Replay.Tracker.SUnitDiedEvent":bt(i,n,r);break;case"NNet.Replay.Tracker.SUnitOwnerChangeEvent":ht(i,n);break}return r.loopGameStart=n.loopGameStart,r.loopLength=n.loopGameEnd,r.length=(n.loopGameEnd-n.loopGameStart)/16,_t(n,e),{playerIDMap:n.playerIDMap}}function dt(t,e,r,n){let i=B(t.m_eventName),a=t.m_intData,s=t.m_stringData,o=t.m_fixedData;switch(i){case"PlayerInit":{let c=v(a,"PlayerID"),l=ae(s,"ToonHandle");c!==void 0&&l&&r[l]&&(e.playerIDMap[c]=l);break}case"GatesOpen":e.loopGameStart=t._gameloop;break;case"LevelUp":{let c=v(a,"PlayerID"),l=v(a,"Level");if(c===void 0||l===void 0)break;let f;if(c>=1&&c<=5)f="0";else if(c>=6&&c<=10)f="1";else break;n.levelTimes[f][String(l)]||(n.levelTimes[f][String(l)]={loop:t._gameloop,level:l,team:f,time:R(t._gameloop,e.loopGameStart)});break}case"TalentChosen":{let c=v(a,"PlayerID"),l=ae(s,"PurchaseName");if(c===void 0||!l||l==="Win"||l==="Loss"||l.startsWith("Hero"))break;let f=n.map?.replace(/\s+/g,"")||"";if(l===f)break;let u=e.playerIDMap[c];if(!u||!r[u])break;let m=["Tier1Choice","Tier2Choice","Tier3Choice","Tier4Choice","Tier5Choice","Tier6Choice","Tier7Choice"];for(let b of m)if(!r[u].talents[b]){r[u].talents[b]=l;break}break}case"PlayerDeath":{let c=v(a,"PlayerID"),l=v(a,"KillingPlayer"),f=w(o,"PositionX")??0,u=w(o,"PositionY")??0;if(c===void 0)break;let m=e.playerIDMap[c];if(!m)break;let b={player:m,hero:r[m]?.hero||""},d=[],h=r[m]?.team;if(l&&l>0){let _=e.playerIDMap[l];_&&r[_]&&d.push({player:_,hero:r[_].hero})}for(let[_,y]of Object.entries(e.playerIDMap)){let x=r[y];!x||x.team===h||parseInt(_)===l||d.push({player:y,hero:x.hero})}let p={loop:t._gameloop,time:R(t._gameloop,e.loopGameStart),x:f,y:u,killers:d,victim:b};n.takedowns.push(p),r[m]&&r[m].deaths.push(p);for(let _ of d)r[_.player]&&r[_.player].takedowns.push(p);break}case"PeriodicXPBreakdown":{let c=v(a,"Team");if(c===void 0)break;let l={GameTime:v(a,"GameTime")??0,PreviousGameTime:v(a,"PreviousGameTime")??0,MinionXP:w(o,"MinionXP")??0,CreepXP:w(o,"CreepXP")??0,StructureXP:w(o,"StructureXP")??0,HeroXP:w(o,"HeroXP")??0,TrickleXP:w(o,"TrickleXP")??0};n.XPBreakdown.push({loop:t._gameloop,time:R(t._gameloop,e.loopGameStart),team:c,teamLevel:v(a,"TeamLevel")??0,breakdown:l,theoreticalMinionXP:v(a,"TheoreticalMinionXP")??0});break}case"EndOfGameXPBreakdown":{let c=v(a,"Team");if(c===void 0)break;n.XPBreakdown.push({loop:t._gameloop,time:R(t._gameloop,e.loopGameStart),team:c,theoreticalMinionXP:v(a,"TheoreticalMinionXP")??0,breakdown:{GameTime:0,PreviousGameTime:0,MinionXP:w(o,"MinionXP")??0,CreepXP:w(o,"CreepXP")??0,StructureXP:w(o,"StructureXP")??0,HeroXP:w(o,"HeroXP")??0,TrickleXP:w(o,"TrickleXP")??0}});break}case"JungleCampCapture":{let c=v(a,"CampTeam")??v(a,"Team")??0;n.mercs.captures.push({loop:t._gameloop,type:ae(s,"CampType")??ae(s,"Result")??"Unknown Camp",team:c,time:R(t._gameloop,e.loopGameStart)});break}case"EndOfGameTalentChoices":{let c=v(a,"PlayerID");if(c===void 0)break;let l=e.playerIDMap[c];if(!l||!r[l])break;let f={};if(s)for(let u of s){let m=B(u.m_key),b=B(u.m_value);m==="Tier 1 Choice"&&b?f.Tier1Choice=b:m==="Tier 2 Choice"&&b?f.Tier2Choice=b:m==="Tier 3 Choice"&&b?f.Tier3Choice=b:m==="Tier 4 Choice"&&b?f.Tier4Choice=b:m==="Tier 5 Choice"&&b?f.Tier5Choice=b:m==="Tier 6 Choice"&&b?f.Tier6Choice=b:m==="Tier 7 Choice"&&b&&(f.Tier7Choice=b)}r[l].talents=f;break}default:mt(i,t,e,n,a,o);break}}var ut=new Set(["SoulEatersSpawned","TributeCollected","RavenCurseActivated","AltarCaptured","SkyTempleShotsFired","DragonKnightActivated","GardenTerrorActivated","InfernalShrineCaptured","PunisherKilled","VolskayaVehicleCapture","BraxisWaveStart","ImmortalDefeated","NukeExploded","PayloadDelivered","AlteracCavalryCharge","AlteracCavalry"]);function mt(t,e,r,n,i,a){if(!ut.has(t)||!i)return;let s=v(i,"Team")??v(i,"Event")??0,o=s===0||s===1?s:0,c={team:s,loop:e._gameloop,time:R(e._gameloop,r.loopGameStart),score:v(i,"Score"),duration:w(a,"Duration")};n.objective[o].events.push(c),n.objective[o].count=n.objective[o].events.length}function pt(t,e,r){let n=B(t.m_unitTypeName),i=t.m_unitTagIndex,a=t.m_unitTagRecycle,s=fe(i,a),o=t.m_controlPlayerId??t.m_upkeepPlayerId,c=t.m_x??0,l=t.m_y??0,f;if(o>=1&&o<=5?f=0:o>=6&&o<=10?f=1:o===11?f=0:o===12?f=1:f=o<=5?0:1,e.unitIndex[s]={type:n,playerId:o,team:f,x:c,y:l,bornLoop:t._gameloop},n.startsWith("Town")&&Oe[n]&&(r.structures[s]={type:n,name:Oe[n],tag:i,rtag:a,x:c,y:l,team:f}),n.startsWith("Hero")&&o>=1&&o<=10){e.heroUnits[s]=o,e.heroLives[o]||(e.heroLives[o]=[]);let u=R(t._gameloop,e.loopGameStart);e.heroLives[o].push({born:u,locations:[{x:c,y:l,time:u}],duration:0})}if(ft[n]){let m=r.mercs.captures[r.mercs.captures.length-1]?.loop??t._gameloop;r.mercs.units[s]={loop:m,team:f,type:n,locations:[{x:c,y:l}],time:R(m,e.loopGameStart),duration:0}}}function bt(t,e,r){let n=fe(t.m_unitTagIndex,t.m_unitTagRecycle),i=R(t._gameloop,e.loopGameStart);r.structures[n]&&(r.structures[n].destroyedLoop=t._gameloop,r.structures[n].destroyed=i),r.mercs.units[n]&&(r.mercs.units[n].duration=i-r.mercs.units[n].time);let a=e.heroUnits[n];if(a!==void 0&&e.heroLives[a]){let s=e.heroLives[a],o=s[s.length-1];o&&o.died===void 0&&(o.died=i,o.duration=i-o.born)}}function ht(t,e){let r=fe(t.m_unitTagIndex,t.m_unitTagRecycle),n=t.m_controlPlayerId??t.m_upkeepPlayerId;e.unitIndex[r]&&(e.unitIndex[r].playerId=n,n>=1&&n<=5?e.unitIndex[r].team=0:n>=6&&n<=10&&(e.unitIndex[r].team=1))}function _t(t,e){for(let[r,n]of Object.entries(t.heroLives)){let i=parseInt(r,10),a=t.playerIDMap[i];if(!a||!e[a])continue;for(let o of n)if(o.died===void 0){let c=o.locations[o.locations.length-1];o.duration=c?c.time-o.born:0}let s="";for(let[o,c]of Object.entries(t.heroUnits))if(c===i){s=o;break}s&&(e[a].units[s]={lives:n})}}var gt=["DamageTaken","CreepDamage","Healing","HeroDamage","MinionDamage","SelfHealing","SiegeDamage","ProtectionGivenToAllies","TeamfightDamageTaken","TeamfightHealingDone","TeamfightHeroDamage","TimeCCdEnemyHeroes","TimeRootingEnemyHeroes","TimeSpentDead","TimeStunningEnemyHeroes","TimeSilencingEnemyHeroes"];function yt(){return{DamageTaken:0,CreepDamage:0,Healing:0,HeroDamage:0,MinionDamage:0,SelfHealing:0,SiegeDamage:0,ProtectionGivenToAllies:0,TeamfightDamageTaken:0,TeamfightHealingDone:0,TeamfightHeroDamage:0,TimeCCdEnemyHeroes:0,TimeRootingEnemyHeroes:0,TimeSpentDead:0,TimeStunningEnemyHeroes:0,TimeSilencingEnemyHeroes:0,avgTimeSpentDead:0,timeDeadPct:0}}function xt(){return{mercCaptures:0,mercUptime:0,mercUptimePercent:0,structures:{},KDA:0,PPK:0,timeTo10:0,totals:yt(),levelAdvTime:0,maxLevelAdv:0,avgLevelAdv:0,levelAdvPct:0,uptime:[],uptimeHistogram:{},wipes:0,avgHeroesAlive:0,aces:0,timeWithHeroAdv:0,pctWithHeroAdv:0,passiveXPRate:0,passiveXPDiff:0,passiveXPGain:0}}function Ne(t,e){St(t),vt(t,e),kt(t,e),wt(t),Et(t,e),Dt(t)}function vt(t,e){for(let r of["0","1"]){let n=t.teams[r];if(!n)continue;n.names=[],n.heroes=[],n.tags=[],n.stats=xt();for(let u of n.ids){let m=e[u];m&&(n.names.push(m.name),n.heroes.push(m.hero),n.tags.push(m.tag))}for(let u of n.ids){let m=e[u];if(m)for(let b of gt){let d=m.gameStats[b];typeof d=="number"&&(n.stats.totals[b]+=d)}}let i=n.ids.reduce((u,m)=>u+(e[m]?.gameStats.Deaths??0),0);i>0&&(n.stats.totals.avgTimeSpentDead=n.stats.totals.TimeSpentDead/i),t.length>0&&(n.stats.totals.timeDeadPct=n.stats.totals.TimeSpentDead/(t.length*n.ids.length));let a=n.takedowns,s=i;n.stats.KDA=s>0?a/s:a,n.stats.PPK=a>0?t.takedowns.filter(u=>n.ids.includes(u.killers[0]?.player)).reduce((u,m)=>u+m.killers.length,0)/a:0;let o=t.levelTimes[r];o?.["10"]&&(n.stats.timeTo10=o[10].time);let c=parseInt(r,10),l=t.mercs.captures.filter(u=>u.team===c);n.stats.mercCaptures=l.length;let f=0;for(let u of Object.values(t.mercs.units))u.team===c&&u.duration>0&&(f+=u.duration);n.stats.mercUptime=f,n.stats.mercUptimePercent=t.length>0?f/t.length:0,Tt(t,n,r)}}function Tt(t,e,r){let n=parseInt(r,10),i=n===0?1:0,a={};for(let s of Object.values(t.structures)){let o=s.name;a[o]||(a[o]={lost:0,destroyed:0,first:t.length}),s.team===i&&s.destroyed!==void 0&&(a[o].destroyed++,a[o].first=Math.min(a[o].first,s.destroyed)),s.team===n&&s.destroyed!==void 0&&a[o].lost++}e.stats.structures=a}function kt(t,e){let r=t.length/60;for(let n of Object.values(e)){let i=n.gameStats,a=i.Deaths??0,s=i.TeamTakedowns??0;r>0&&(i.DPM=(i.HeroDamage??0)/r,i.HPM=((i.Healing??0)+(i.SelfHealing??0))/r,i.XPM=(i.ExperienceContribution??0)/r),i.KDA=a>0?(i.Takedowns??0)/a:i.Takedowns??0,i.KillParticipation=s>0?(i.Takedowns??0)/s:0,i.damageDonePerDeath=a>0?(i.HeroDamage??0)/a:i.HeroDamage??0,i.damageTakenPerDeath=a>0?(i.DamageTaken??0)/a:i.DamageTaken??0,i.healingDonePerDeath=a>0?((i.Healing??0)+(i.SelfHealing??0))/a:(i.Healing??0)+(i.SelfHealing??0),i.length=t.length}}function St(t){let e=0,r=0,n=new Set(t.teams[0]?.ids||[]);for(let i of t.takedowns)n.has(i.victim.player)?r++:e++;t.team0Takedowns=e,t.team1Takedowns=r,t.teams[0]&&(t.teams[0].takedowns=e),t.teams[1]&&(t.teams[1].takedowns=r)}function wt(t){let e=t.levelTimes[0]||{},r=t.levelTimes[1]||{},n=[];for(let l of Object.values(e))n.push({time:l.time,team:0,level:l.level});for(let l of Object.values(r))n.push({time:l.time,team:1,level:l.level});if(n.sort((l,f)=>l.time-f.time),n.length===0){t.levelAdvTimeline=[];return}let i=[],a=0,s=0,o=n[0].time;for(let l of n){let f=a-s;l.time>o&&i.push({start:o,end:l.time,levelDiff:f,length:l.time-o}),l.team===0?a=l.level:s=l.level,o=l.time}let c=a-s;t.length>o&&i.push({start:o,end:t.length,levelDiff:c,length:t.length-o}),t.levelAdvTimeline=i;for(let l of["0","1"]){let f=t.teams[l];if(!f)continue;let u=l==="0"?1:-1,m=0,b=0,d=0,h=0;for(let p of i){let _=p.levelDiff*u;_>0&&(m+=p.length),b=Math.max(b,_),d+=_*p.length,h+=p.length}f.stats.levelAdvTime=m,f.stats.maxLevelAdv=b,f.stats.avgLevelAdv=h>0?d/h:0,f.stats.levelAdvPct=t.length>0?m/t.length:0}}function Et(t,e){for(let a of["0","1"]){let s=t.teams[a];if(!s)continue;let o=[];for(let p of s.ids){let _=e[p];if(_)for(let y of _.deaths){o.push({time:y.time,delta:-1});let x=y.time+Pt(_.gameStats.Level??1);x<t.length&&o.push({time:x,delta:1})}}o.sort((p,_)=>p.time-_.time);let c=[{time:0,heroes:s.ids.length}],l=s.ids.length;for(let p of o)l+=p.delta,l=Math.max(0,Math.min(s.ids.length,l)),c.push({time:p.time,heroes:l});s.stats.uptime=c;let f={};for(let p=0;p<c.length;p++){let y=(p<c.length-1?c[p+1].time:t.length)-c[p].time,x=String(c[p].heroes);f[x]=(f[x]||0)+y}s.stats.uptimeHistogram=f;let u=0,m=0;for(let p=0;p<c.length;p++){let y=(p<c.length-1?c[p+1].time:t.length)-c[p].time;u+=c[p].heroes*y,m+=y}s.stats.avgHeroesAlive=m>0?u/m:s.ids.length,s.stats.wipes=c.filter(p=>p.heroes===0).length,s.stats.aces=0;let b=a==="0"?"1":"0",d=t.teams[b];d?.stats?.uptime&&(s.stats.aces=d.stats.uptime.filter(p=>p.heroes===0).length);let h=t.XPBreakdown.filter(p=>p.team===parseInt(a,10));if(h.length>0){let _=h[h.length-1].breakdown.TrickleXP;s.stats.passiveXPGain=_,s.stats.passiveXPRate=t.length>0?_/(t.length/60):0}}for(let a of["0","1"]){let s=t.teams[a],o=a==="0"?"1":"0",c=t.teams[o];if(!s||!c)continue;let l=s.stats.uptime,f=c.stats.uptime;if(!l.length||!f.length)continue;let u=new Set;for(let d of l)u.add(d.time);for(let d of f)u.add(d.time);let m=Array.from(u).sort((d,h)=>d-h),b=0;for(let d=0;d<m.length;d++){let h=m[d],_=(d<m.length-1?m[d+1]:t.length)-h,y=ze(l,h),x=ze(f,h);y>x&&(b+=_)}s.stats.timeWithHeroAdv=b,s.stats.pctWithHeroAdv=t.length>0?b/t.length:0}let r=t.teams[0]?.stats.passiveXPRate??0,n=t.teams[1]?.stats.passiveXPRate??0,i=(r+n)/2;t.teams[0]&&(t.teams[0].stats.passiveXPDiff=i>0?r/i:0),t.teams[1]&&(t.teams[1].stats.passiveXPDiff=i>0?n/i:0)}function ze(t,e){let r=0;for(let n of t)if(n.time<=e)r=n.heroes;else break;return r}function Pt(t){return t<=1?15:t<=5?15+(t-1)*2:t<=10?23+(t-5)*3:t<=15?38+(t-10)*4:58+(t-15)*5}function Dt(t){let e=1/0,r=-1,n=1/0,i=-1;for(let s of Object.values(t.structures))s.destroyed!==void 0&&(s.name==="Fort"&&s.destroyed<e&&(e=s.destroyed,r=s.team===0?1:0),s.name==="Keep"&&s.destroyed<n&&(n=s.destroyed,i=s.team===0?1:0));r>=0&&(t.firstFort=r,t.firstFortWin=r===t.winner),i>=0&&(t.firstKeep=i,t.firstKeepWin=i===t.winner);let a=[...t.objective[0].events.map(s=>({...s,assignedTeam:0})),...t.objective[1].events.map(s=>({...s,assignedTeam:1}))].sort((s,o)=>s.loop-o.loop);a.length>0&&(t.firstObjective=a[0].assignedTeam,t.firstObjectiveWin=a[0].assignedTeam===t.winner),t.firstPickWin=t.picks.first===t.winner}function k(t){return Buffer.isBuffer(t)?t.toString("utf8"):typeof t=="string"?t:String(t??"")}var se=class{static async analyze(e){try{let r=new M(e);await r.init();let n=r.getDetails();if(!n)throw new Error("Missing replay.details from parsed MPQ archive");let i=r.getTrackerEvents(),a=r.getInitData(),o=r.getHeader()?.m_version??{},c={m_flags:o.m_flags??0,m_major:o.m_major??0,m_minor:o.m_minor??0,m_revision:o.m_revision??0,m_build:o.m_baseBuild??r.getBuild(),m_baseBuild:o.m_baseBuild??r.getBuild()},l=n.m_playerList.find(b=>b?.m_toon)?.m_toon,f={version:c,map:k(n.m_title),isBlizzardMap:n.m_isBlizzardMap,timeLocalOffset:Number(n.m_timeLocalOffset),gameSpeed:n.m_gameSpeed,date:this.fileTimeToDate(n.m_timeUTC).toISOString(),rawDate:Number(n.m_timeUTC),length:0,winner:-1,region:l?.m_region,playerIDs:[],heroes:[],levelTimes:{0:{},1:{}},bans:{0:[],1:[]},picks:{0:[],1:[],first:0},XPBreakdown:[],takedowns:[],mercs:{captures:[],units:{}},team0Takedowns:0,team1Takedowns:0,structures:{},objective:{0:{count:0,events:[]},1:{count:0,events:[]},type:""},teams:{0:this.emptyTeam(),1:this.emptyTeam()},winningPlayers:[],levelAdvTimeline:[],firstPickWin:!1};f.objective.type=f.map||"";let u={};for(let b of n.m_playerList){if(!b?.m_toon)continue;let d=b.m_toon,h=k(d.m_programId),p=`${d.m_region}-${h}-${d.m_realm}-${d.m_id}`,_=k(b.m_hero),y=q(_)||_;u[p]={hero:y,name:k(b.m_name),uuid:d.m_id,region:d.m_region,realm:d.m_realm,ToonHandle:p,tag:0,team:b.m_teamId,win:b.m_result===1,skin:"",mount:"",banner:"",spray:"",clanTag:"",highestLeague:0,combinedRaceLevels:0,randomSeed:0,announcer:"",silenced:!1,voiceSilenced:!1,gameStats:{},awards:[],talents:{},takedowns:[],deaths:[],units:{}},f.playerIDs.push(p),f.heroes.push(y)}this.extractBattleTags(r,n,u),this.extractDraft(a,f,n),this.extractCosmetics(a,n,u);let{playerIDMap:m}=Ue(i,u,f);this.processScoreEvents(i,m,u);for(let[b,d]of Object.entries(u)){d.win&&(f.winner=d.team,f.winningPlayers.push(b));let h=f.teams[d.team.toString()];h&&(h.level=Math.max(h.level,d.gameStats.Level||0),h.ids.push(b))}return Ne(f,u),{status:1,match:f,players:u}}catch(r){return console.error("ReplayAnalyzer Error:",r),{status:-2,error:String(r)}}}static emptyTeam(){return{level:0,takedowns:0,ids:[],names:[],heroes:[],tags:[],stats:{mercCaptures:0,mercUptime:0,mercUptimePercent:0,structures:{},KDA:0,PPK:0,timeTo10:0,totals:{DamageTaken:0,CreepDamage:0,Healing:0,HeroDamage:0,MinionDamage:0,SelfHealing:0,SiegeDamage:0,ProtectionGivenToAllies:0,TeamfightDamageTaken:0,TeamfightHealingDone:0,TeamfightHeroDamage:0,TimeCCdEnemyHeroes:0,TimeRootingEnemyHeroes:0,TimeSpentDead:0,TimeStunningEnemyHeroes:0,TimeSilencingEnemyHeroes:0,avgTimeSpentDead:0,timeDeadPct:0},levelAdvTime:0,maxLevelAdv:0,avgLevelAdv:0,levelAdvPct:0,uptime:[],uptimeHistogram:{},wipes:0,avgHeroesAlive:0,aces:0,timeWithHeroAdv:0,pctWithHeroAdv:0,passiveXPRate:0,passiveXPDiff:0,passiveXPGain:0}}}static extractBattleTags(e,r,n){let i=e.extractFile("replay.server.battlelobby");if(i)try{let a=new RegExp("([\\p{L}\\d]{3,24}#\\d{4,10})[z\xD8]?","gu"),s=i.toString("utf8").match(a);if(!s)return;let o=0;for(let c of r.m_playerList){if(!c?.m_toon)continue;let l=k(c.m_name);for(;o<s.length;){let u=s[o].split("#"),m=u[0],b=u[1].replace(/[zØ]/g,"");if(o++,m===l){let d=c.m_toon,h=`${d.m_region}-${k(d.m_programId)}-${d.m_realm}-${d.m_id}`;n[h]&&(n[h].tag=parseInt(b,10)||0);break}}}}catch(a){console.error("BattleTag regex error:",a)}}static extractDraft(e,r,n){if(e)try{let i=e.m_syncLobbyState;if(!i)return;let a=i.m_lobbyState,s=i.m_gameDescription;if(!a)return;s&&(r.randomValue=s.m_randomValue,r.gameOptions=s.m_gameOptions);let o=[],c=[];for(let d of n.m_playerList){if(!d?.m_toon)continue;let h=k(d.m_hero),p=q(h)||h;d.m_teamId===0?o.push(p):d.m_teamId===1&&c.push(p)}r.picks={0:o,1:c,first:0};let l,f=s?.m_gameOptions;if(f&&typeof f.m_ammId=="number"){let d=f.m_ammId;d===50001?l="Quick Match":d===50031?l="ARAM":d===50041?l="Unranked Draft":d===50051?l="Custom":d===50061?l="Hero League":d===50071?l="Team League":d===50091&&(l="Storm League")}if(!l&&typeof a.m_gameMode=="number"){let d=a.m_gameMode;d===3?l="Quick Match":d===4?l="Custom":d===5?l="Hero League":d===6?l="Team League":d===7?l="Unranked Draft":d===8&&(l="ARAM")}if(r.mode=l,typeof a.m_gameType=="number"&&(r.type=a.m_gameType),!a.m_slots)return;let m=a.m_pickedMapTag,b=0;m!==void 0&&(b=a.m_firstPickTeam??0,r.picks.first=b)}catch{}}static extractCosmetics(e,r,n){if(e)try{let i=e.m_syncLobbyState;if(!i)return;let a=i.m_lobbyState;if(!a)return;let s=a.m_slots,o=i.m_userInitialData;if(!s)return;let c=0;for(let l of r.m_playerList){if(!l?.m_toon)continue;let f=l.m_toon,u=`${f.m_region}-${k(f.m_programId)}-${f.m_realm}-${f.m_id}`,m=n[u];for(;c<s.length;){let b=s[c];c++;let d=b.m_hero;if(!(!d||Buffer.isBuffer(d)&&d.length===0)){if(m&&(m.skin=k(b.m_skin)||"",m.mount=k(b.m_mount)||"",m.announcer=k(b.m_announcerPack)||"",m.banner=k(b.m_banner)||"",m.spray=k(b.m_spray)||"",m.silenced=!!b.m_hasSilencePenalty,m.voiceSilenced=!!b.m_hasVoiceSilencePenalty,o)){let h=o.find(p=>k(p.m_name)===m.name);h&&(m.clanTag=k(h.m_clanTag),m.highestLeague=h.m_highestLeague,m.combinedRaceLevels=h.m_combinedRaceLevels,m.randomSeed=h.m_randomSeed)}break}}}}catch{}}static processScoreEvents(e,r,n){for(let i of e){if(i._event!=="NNet.Replay.Tracker.SScoreResultEvent")continue;let a=i.m_instanceList;for(let s of a){let o=k(s.m_name),c=s.m_values,l=o.startsWith("EndOfMatchAward"),f=0;for(let u of c)if(u&&u.length>0&&u[0]!==void 0){let m=f+1,b=r[m];if(b&&n[b]){let d=typeof u[0]=="object"&&u[0]!==null&&"m_value"in u[0]?u[0].m_value:u[0];d!=null&&(l?d===1&&n[b].awards.push(o):n[b].gameStats[o]=d)}f++}else u&&u.length===0&&f++}}}static fileTimeToDate(e){return new Date(Number(e)/1e4-116444736e5)}};0&&(module.exports={LiveStreamParser,ReplayAnalyzer,ReplayParser});
|
|
1
|
+
"use strict";var Fe=Object.create;var Y=Object.defineProperty;var Xe=Object.getOwnPropertyDescriptor;var Ge=Object.getOwnPropertyNames;var Ke=Object.getPrototypeOf,je=Object.prototype.hasOwnProperty;var K=(r,e)=>()=>(e||r((e={exports:{}}).exports,e),e.exports),Qe=(r,e)=>{for(var t in e)Y(r,t,{get:e[t],enumerable:!0})},pe=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Ge(e))!je.call(r,i)&&i!==t&&Y(r,i,{get:()=>e[i],enumerable:!(n=Xe(e,i))||n.enumerable});return r};var J=(r,e,t)=>(t=r!=null?Fe(Ke(r)):{},pe(e||!r||!r.__esModule?Y(t,"default",{value:r,enumerable:!0}):t,r)),Ve=r=>pe(Y({},"__esModule",{value:!0}),r);var _e=K((Ct,he)=>{"use strict";var be=[0,1,3,7,15,31,63,127,255],j=function(r){this.stream=r,this.bitOffset=0,this.curByte=0,this.hasByte=!1};j.prototype._ensureByte=function(){this.hasByte||(this.curByte=this.stream.readByte(),this.hasByte=!0)};j.prototype.read=function(r){for(var e=0;r>0;){this._ensureByte();var t=8-this.bitOffset;if(r>=t)e<<=t,e|=be[t]&this.curByte,this.hasByte=!1,this.bitOffset=0,r-=t;else{e<<=r;var n=t-r;e|=(this.curByte&be[r]<<n)>>n,this.bitOffset+=r,r=0}}return e};j.prototype.seek=function(r){var e=r%8,t=(r-e)/8;this.bitOffset=e,this.stream.seek(t),this.hasByte=!1};j.prototype.pi=function(){var r=new Buffer(6),e;for(e=0;e<r.length;e++)r[e]=this.read(8);return r.toString("hex")};he.exports=j});var ye=K((It,ge)=>{"use strict";var O=function(){};O.prototype.readByte=function(){throw new Error("abstract method readByte() not implemented")};O.prototype.read=function(r,e,t){for(var n=0;n<t;){var i=this.readByte();if(i<0)return n===0?-1:n;r[e++]=i,n++}return n};O.prototype.seek=function(r){throw new Error("abstract method seek() not implemented")};O.prototype.writeByte=function(r){throw new Error("abstract method readByte() not implemented")};O.prototype.write=function(r,e,t){var n;for(n=0;n<t;n++)this.writeByte(r[e++]);return t};O.prototype.flush=function(){};ge.exports=O});var ve=K((At,xe)=>{"use strict";xe.exports=(function(){var r=new Uint32Array([0,79764919,159529838,222504665,319059676,398814059,445009330,507990021,638119352,583659535,797628118,726387553,890018660,835552979,1015980042,944750013,1276238704,1221641927,1167319070,1095957929,1595256236,1540665371,1452775106,1381403509,1780037320,1859660671,1671105958,1733955601,2031960084,2111593891,1889500026,1952343757,2552477408,2632100695,2443283854,2506133561,2334638140,2414271883,2191915858,2254759653,3190512472,3135915759,3081330742,3009969537,2905550212,2850959411,2762807018,2691435357,3560074640,3505614887,3719321342,3648080713,3342211916,3287746299,3467911202,3396681109,4063920168,4143685023,4223187782,4286162673,3779000052,3858754371,3904687514,3967668269,881225847,809987520,1023691545,969234094,662832811,591600412,771767749,717299826,311336399,374308984,453813921,533576470,25881363,88864420,134795389,214552010,2023205639,2086057648,1897238633,1976864222,1804852699,1867694188,1645340341,1724971778,1587496639,1516133128,1461550545,1406951526,1302016099,1230646740,1142491917,1087903418,2896545431,2825181984,2770861561,2716262478,3215044683,3143675388,3055782693,3001194130,2326604591,2389456536,2200899649,2280525302,2578013683,2640855108,2418763421,2498394922,3769900519,3832873040,3912640137,3992402750,4088425275,4151408268,4197601365,4277358050,3334271071,3263032808,3476998961,3422541446,3585640067,3514407732,3694837229,3640369242,1762451694,1842216281,1619975040,1682949687,2047383090,2127137669,1938468188,2001449195,1325665622,1271206113,1183200824,1111960463,1543535498,1489069629,1434599652,1363369299,622672798,568075817,748617968,677256519,907627842,853037301,1067152940,995781531,51762726,131386257,177728840,240578815,269590778,349224269,429104020,491947555,4046411278,4126034873,4172115296,4234965207,3794477266,3874110821,3953728444,4016571915,3609705398,3555108353,3735388376,3664026991,3290680682,3236090077,3449943556,3378572211,3174993278,3120533705,3032266256,2961025959,2923101090,2868635157,2813903052,2742672763,2604032198,2683796849,2461293480,2524268063,2284983834,2364738477,2175806836,2238787779,1569362073,1498123566,1409854455,1355396672,1317987909,1246755826,1192025387,1137557660,2072149281,2135122070,1912620623,1992383480,1753615357,1816598090,1627664531,1707420964,295390185,358241886,404320391,483945776,43990325,106832002,186451547,266083308,932423249,861060070,1041341759,986742920,613929101,542559546,756411363,701822548,3316196985,3244833742,3425377559,3370778784,3601682597,3530312978,3744426955,3689838204,3819031489,3881883254,3928223919,4007849240,4037393693,4100235434,4180117107,4259748804,2310601993,2373574846,2151335527,2231098320,2596047829,2659030626,2470359227,2550115596,2947551409,2876312838,2788305887,2733848168,3165939309,3094707162,3040238851,2985771188]),e=function(){var t=4294967295;this.getCRC=function(){return~t>>>0},this.updateCRC=function(n){t=t<<8^r[(t>>>24^n)&255]},this.updateCRCRun=function(n,i){for(;i-- >0;)t=t<<8^r[(t>>>24^n)&255]}};return e})()});var Te=K((Mt,We)=>{We.exports={name:"seek-bzip",version:"2.0.0",contributors:["C. Scott Ananian (http://cscott.net)","Eli Skeggs","Kevin Kwok","Rob Landley (http://landley.net)"],description:"a pure-JavaScript Node.JS module for random-access decoding bzip2 data",main:"./lib/index.js",repository:{type:"git",url:"https://github.com/cscott/seek-bzip.git"},license:"MIT",bin:{"seek-bunzip":"./bin/seek-bunzip","seek-table":"./bin/seek-bzip-table"},directories:{test:"test"},dependencies:{commander:"^6.0.0"},devDependencies:{fibers:"^5.0.0",mocha:"^8.1.0"},scripts:{test:"mocha"}}});var Be=K((Ht,Re)=>{"use strict";var $e=_e(),Q=ye(),Ee=ve(),Pe=Te(),ee=20,ke=258,Se=0,qe=1,Ze=2,Ye=6,Je=50,et="314159265359",tt="177245385090",we=function(r,e){var t=r[e],n;for(n=e;n>0;n--)r[n]=r[n-1];return r[0]=t,t},g={OK:0,LAST_BLOCK:-1,NOT_BZIP_DATA:-2,UNEXPECTED_INPUT_EOF:-3,UNEXPECTED_OUTPUT_EOF:-4,DATA_ERROR:-5,OUT_OF_MEMORY:-6,OBSOLETE_INPUT:-7,END_OF_BLOCK:-8},I={};I[g.LAST_BLOCK]="Bad file checksum";I[g.NOT_BZIP_DATA]="Not bzip data";I[g.UNEXPECTED_INPUT_EOF]="Unexpected input EOF";I[g.UNEXPECTED_OUTPUT_EOF]="Unexpected output EOF";I[g.DATA_ERROR]="Data error";I[g.OUT_OF_MEMORY]="Out of memory";I[g.OBSOLETE_INPUT]="Obsolete (pre 0.9.5) bzip format not supported.";var T=function(r,e){var t=I[r]||"unknown error";e&&(t+=": "+e);var n=new TypeError(t);throw n.errorCode=r,n},S=function(r,e){this.writePos=this.writeCurrent=this.writeCount=0,this._start_bunzip(r,e)};S.prototype._init_block=function(){var r=this._get_next_block();return r?(this.blockCRC=new Ee,!0):(this.writeCount=-1,!1)};S.prototype._start_bunzip=function(r,e){var t=new Buffer(4);(r.read(t,0,4)!==4||String.fromCharCode(t[0],t[1],t[2])!=="BZh")&&T(g.NOT_BZIP_DATA,"bad magic");var n=t[3]-48;(n<1||n>9)&&T(g.NOT_BZIP_DATA,"level out of range"),this.reader=new $e(r),this.dbufSize=1e5*n,this.nextoutput=0,this.outputStream=e,this.streamCRC=0};S.prototype._get_next_block=function(){var r,e,t,n=this.reader,i=n.pi();if(i===tt)return!1;i!==et&&T(g.NOT_BZIP_DATA),this.targetBlockCRC=n.read(32)>>>0,this.streamCRC=(this.targetBlockCRC^(this.streamCRC<<1|this.streamCRC>>>31))>>>0,n.read(1)&&T(g.OBSOLETE_INPUT);var a=n.read(24);a>this.dbufSize&&T(g.DATA_ERROR,"initial position out of bounds");var o=n.read(16),s=new Buffer(256),c=0;for(r=0;r<16;r++)if(o&1<<15-r){var l=r*16;for(t=n.read(16),e=0;e<16;e++)t&1<<15-e&&(s[c++]=l+e)}var f=n.read(3);(f<Ze||f>Ye)&&T(g.DATA_ERROR);var u=n.read(15);u===0&&T(g.DATA_ERROR);var m=new Buffer(256);for(r=0;r<f;r++)m[r]=r;var b=new Buffer(u);for(r=0;r<u;r++){for(e=0;n.read(1);e++)e>=f&&T(g.DATA_ERROR);b[r]=we(m,e)}var d=c+2,h=[],p;for(e=0;e<f;e++){var _=new Buffer(d),y=new Uint16Array(ee+1);for(o=n.read(5),r=0;r<d;r++){for(;(o<1||o>ee)&&T(g.DATA_ERROR),!!n.read(1);)n.read(1)?o--:o++;_[r]=o}var x,D;for(x=D=_[0],r=1;r<d;r++)_[r]>D?D=_[r]:_[r]<x&&(x=_[r]);p={},h.push(p),p.permute=new Uint16Array(ke),p.limit=new Uint32Array(ee+2),p.base=new Uint32Array(ee+1),p.minLen=x,p.maxLen=D;var H=0;for(r=x;r<=D;r++)for(y[r]=p.limit[r]=0,o=0;o<d;o++)_[o]===r&&(p.permute[H++]=o);for(r=0;r<d;r++)y[_[r]]++;for(H=o=0,r=x;r<D;r++)H+=y[r],p.limit[r]=H-1,H<<=1,o+=y[r],p.base[r+1]=H-o;p.limit[D+1]=Number.MAX_VALUE,p.limit[D]=H+y[D]-1,p.base[x]=0}var N=new Uint32Array(256);for(r=0;r<256;r++)m[r]=r;var L=0,C=0,de=0,E,X=this.dbuf=new Uint32Array(this.dbufSize);for(d=0;;){for(d--||(d=Je-1,de>=u&&T(g.DATA_ERROR),p=h[b[de++]]),r=p.minLen,e=n.read(r);r>p.maxLen&&T(g.DATA_ERROR),!(e<=p.limit[r]);r++)e=e<<1|n.read(1);e-=p.base[r],(e<0||e>=ke)&&T(g.DATA_ERROR);var G=p.permute[e];if(G===Se||G===qe){L||(L=1,o=0),G===Se?o+=L:o+=2*L,L<<=1;continue}if(L)for(L=0,C+o>this.dbufSize&&T(g.DATA_ERROR),E=s[m[0]],N[E]+=o;o--;)X[C++]=E;if(G>c)break;C>=this.dbufSize&&T(g.DATA_ERROR),r=G-1,E=we(m,r),E=s[E],N[E]++,X[C++]=E}for((a<0||a>=C)&&T(g.DATA_ERROR),e=0,r=0;r<256;r++)t=e+N[r],N[r]=e,e=t;for(r=0;r<C;r++)E=X[r]&255,X[N[E]]|=r<<8,N[E]++;var Z=0,ue=0,me=0;return C&&(Z=X[a],ue=Z&255,Z>>=8,me=-1),this.writePos=Z,this.writeCurrent=ue,this.writeCount=C,this.writeRun=me,!0};S.prototype._read_bunzip=function(r,e){var t,n,i;if(this.writeCount<0)return 0;for(var a=0,o=this.dbuf,s=this.writePos,c=this.writeCurrent,l=this.writeCount,f=this.outputsize,u=this.writeRun;l;){for(l--,n=c,s=o[s],c=s&255,s>>=8,u++===3?(t=c,i=n,c=-1):(t=1,i=c),this.blockCRC.updateCRCRun(i,t);t--;)this.outputStream.writeByte(i),this.nextoutput++;c!=n&&(u=0)}return this.writeCount=l,this.blockCRC.getCRC()!==this.targetBlockCRC&&T(g.DATA_ERROR,"Bad block CRC (got "+this.blockCRC.getCRC().toString(16)+" expected "+this.targetBlockCRC.toString(16)+")"),this.nextoutput};var se=function(r){if("readByte"in r)return r;var e=new Q;return e.pos=0,e.readByte=function(){return r[this.pos++]},e.seek=function(t){this.pos=t},e.eof=function(){return this.pos>=r.length},e},De=function(r){var e=new Q,t=!0;if(r)if(typeof r=="number")e.buffer=new Buffer(r),t=!1;else{if("writeByte"in r)return r;e.buffer=r,t=!1}else e.buffer=new Buffer(16384);return e.pos=0,e.writeByte=function(n){if(t&&this.pos>=this.buffer.length){var i=new Buffer(this.buffer.length*2);this.buffer.copy(i),this.buffer=i}this.buffer[this.pos++]=n},e.getBuffer=function(){if(this.pos!==this.buffer.length){if(!t)throw new TypeError("outputsize does not match decoded input");var n=new Buffer(this.pos);this.buffer.copy(n,0,0,this.pos),this.buffer=n}return this.buffer},e._coerced=!0,e};S.Err=g;S.decode=function(r,e,t){for(var n=se(r),i=De(e),a=new S(n,i);!("eof"in n&&n.eof());)if(a._init_block())a._read_bunzip();else{var o=a.reader.read(32)>>>0;if(o!==a.streamCRC&&T(g.DATA_ERROR,"Bad stream CRC (got "+a.streamCRC.toString(16)+" expected "+o.toString(16)+")"),t&&"eof"in n&&!n.eof())a._start_bunzip(n,i);else break}if("getBuffer"in i)return i.getBuffer()};S.decodeBlock=function(r,e,t){var n=se(r),i=De(t),a=new S(n,i);a.reader.seek(e);var o=a._get_next_block();if(o&&(a.blockCRC=new Ee,a.writeCopies=0,a._read_bunzip()),"getBuffer"in i)return i.getBuffer()};S.table=function(r,e,t){var n=new Q;n.delegate=se(r),n.pos=0,n.readByte=function(){return this.pos++,this.delegate.readByte()},n.delegate.eof&&(n.eof=n.delegate.eof.bind(n.delegate));var i=new Q;i.pos=0,i.writeByte=function(){this.pos++};for(var a=new S(n,i),o=a.dbufSize;!("eof"in n&&n.eof());){var s=n.pos*8+a.reader.bitOffset;if(a.reader.hasByte&&(s-=8),a._init_block()){var c=i.pos;a._read_bunzip(),e(s,i.pos-c)}else{var l=a.reader.read(32);if(t&&"eof"in n&&!n.eof())a._start_bunzip(n,i),console.assert(a.dbufSize===o,"shouldn't change block size within multistream file");else break}}};S.Stream=Q;S.version=Pe.version;S.license=Pe.license;Re.exports=S});var Rt={};Qe(Rt,{LiveStreamParser:()=>ie,ReplayAnalyzer:()=>oe,ReplayParser:()=>M});module.exports=Ve(Rt);var Ae=J(require("fs")),V=J(require("zlib")),rt=Be(),Ce=512,nt=65536,it=16777216,at=67108864,ot=2147483648,st={TABLE_OFFSET:0,HASH_A:1,HASH_B:2,TABLE:3};function ct(){let r=1048577,e=new Uint32Array(256*5);for(let t=0;t<256;t++){let n=t;for(let i=0;i<5;i++){r=(r*125+3)%2796203;let a=(r&65535)<<16;r=(r*125+3)%2796203;let o=r&65535;e[n]=(a|o)>>>0,n+=256}}return e}var Ie=ct(),te=class{file;header;hashTable;blockTable;files;constructor(e,t=!0){if(Buffer.isBuffer(e)?this.file=e:this.file=Ae.readFileSync(e),this.header=this.readHeader(),this.hashTable=this.readTable("hash"),this.blockTable=this.readTable("block"),t){let n=this.readFile("(listfile)");n?this.files=n.toString("utf8").trim().split(`\r
|
|
2
|
+
`):this.files=null}else this.files=null}readHeader(){let e=this.file.toString("utf8",0,4),t;if(e==="MPQ")t=this.readMPQHeader(),t.offset=0;else if(e==="MPQ\x1B"){let n=this.readMPQUserDataHeader();t=this.readMPQHeader(n.mpqHeaderOffset),t.offset=n.mpqHeaderOffset,t.userDataHeader=n}else throw new Error("Invalid MPQ file header");return t}readMPQHeader(e=0){let t=this.file.subarray(e,e+32),n={magic:t.toString("utf8",0,4),headerSize:t.readUInt32LE(4),archiveSize:t.readUInt32LE(8),formatVersion:t.readUInt16LE(12),sectorSizeShift:t.readUInt16LE(14),hashTableOffset:t.readUInt32LE(16),blockTableOffset:t.readUInt32LE(20),hashTableEntries:t.readUInt32LE(24),blockTableEntries:t.readUInt32LE(28)};if(n.formatVersion===1){let i=this.file.subarray(e+32,e+32+12);n.extendedBlockTableOffset=i.readUInt32LE(0)+i.readUInt32LE(4)*4294967296,n.hashTableOffsetHigh=i.readInt8(8),n.blockTableOffsetHigh=i.readInt8(10)}return n}readMPQUserDataHeader(){let e=this.file.subarray(0,16),t={magic:e.toString("utf8",0,4),userDataSize:e.readUInt32LE(4),mpqHeaderOffset:e.readUInt32LE(8),userDataHeaderSize:e.readUInt32LE(12)};return t.content=this.file.subarray(16,16+t.userDataHeaderSize),t}readTable(e){let t=e==="hash"?"hashTableOffset":"blockTableOffset",n=e==="hash"?"hashTableEntries":"blockTableEntries",i=this.header[t],a=this.header[n];if(i==null||a==null)throw new Error("Missing "+e+" offset or entries");let o=this.hash("("+e+" table)","TABLE"),s=this.file.subarray(i+(this.header.offset||0),i+(this.header.offset||0)+a*16);s=this.decrypt(s,o);let c=[];for(let l=0;l<a;l++){let f=s.subarray(l*16,l*16+16);e==="hash"?c.push({hashA:f.readUInt32LE(0),hashB:f.readUInt32LE(4),locale:f.readUInt16LE(8),platform:f.readUInt16LE(10),blockTableIndex:f.readUInt32LE(12)}):c.push({offset:f.readUInt32LE(0),archivedSize:f.readUInt32LE(4),size:f.readUInt32LE(8),flags:f.readUInt32LE(12)})}return c}getHashTableEntry(e){let t=this.hash(e,"HASH_A"),n=this.hash(e,"HASH_B");for(let i of this.hashTable)if(i.hashA===t&&i.hashB===n)return i}readFile(e,t=!1){function n(c){let l=c[0];if(l===0)return c;if(l===2)return V.inflateSync(c.subarray(1));if(l===16)return rt.decode(c.subarray(1));try{return V.inflateSync(c.subarray(1))}catch{return V.inflateRawSync(c.subarray(1))}}let i=this.getHashTableEntry(e);if(!i)return null;let a=this.blockTable[i.blockTableIndex];if(!a||!(a.flags&ot))return null;if(a.archivedSize===0)return Buffer.alloc(0);let o=a.offset+(this.header.offset||0),s=this.file.subarray(o,o+a.archivedSize);if(a.flags&nt)throw new Error("Encryption is not supported");if(a.flags&it)a.flags&Ce&&(t||a.size>a.archivedSize)&&(s=n(s));else{let c=512<<this.header.sectorSizeShift,l=Math.trunc(a.size/c)+1,f=!1;a.flags&at&&(f=!0,l+=1);let u=[];for(let h=0;h<l+1;h++)u.push(s.readUInt32LE(4*h));let m=u.length-(f?2:1),b=[],d=a.size;for(let h=0;h<m;h++){let p=s.subarray(u[h],u[h+1]);a.flags&Ce&&(t||d>p.length)&&(p=n(p)),d-=p.length,b.push(p)}s=Buffer.concat(b)}return s}hash(e,t){let n=2146271213,i=4008636142;for(let a=0;a<e.length;a++){let o=e.toUpperCase().charCodeAt(a);n=(Ie[(st[t]<<8)+o]^n+i)>>>0,i=o+n+i+(i<<5)+3>>>0}return n}decrypt(e,t){let n=t>>>0,i=4008636142,a=Buffer.alloc(e.length),o=e.length/4;for(let s=0;s<o;s++){i=i+Ie[1024+(n&255)]>>>0;let c=e.readUInt32LE(s*4);c=(c^n+i)>>>0,n=((~n<<21)+286331153|n>>>11)>>>0,i=c+i+(i<<5)+3>>>0,a.writeUInt32LE(c,s*4)}return a}};var W=class extends Error{constructor(e="Truncated Buffer"){super(e),this.name="TruncatedError"}},U=class extends Error{constructor(e="Corrupted Buffer"){super(e),this.name="CorruptedError"}},$=class{_data;_used;_next;_nextbits;_bigendian;constructor(e,t="big"){this._data=e,this._used=0,this._next=0,this._nextbits=0,this._bigendian=t==="big"}done(){return this._nextbits===0&&this._used>=this._data.length}used_bits(){return this._used*8-this._nextbits}byte_align(){this._nextbits=0}read_aligned_bytes(e){if(this.byte_align(),this._used+e>this._data.length)throw new W;let t=this._data.subarray(this._used,this._used+e);return this._used+=e,t}read_bits(e){let t=0,n=0;for(;n!==e;){if(this._nextbits===0){if(this.done())throw new W;this._next=this._data[this._used],this._used+=1,this._nextbits=8}let i=Math.min(e-n,this._nextbits),a=this._next&(1<<i)-1;this._bigendian?t+=a*Math.pow(2,e-n-i):t+=a*Math.pow(2,n),this._next>>=i,this._nextbits-=i,n+=i}return t}read_bits_bigint(e){let t=0n,n=0;for(;n!==e;){if(this._nextbits===0){if(this.done())throw new W;this._next=this._data[this._used],this._used+=1,this._nextbits=8}let i=Math.min(e-n,this._nextbits),a=BigInt(this._next&(1<<i)-1);this._bigendian?t|=a<<BigInt(e-n-i):t|=a<<BigInt(n),this._next>>=i,this._nextbits-=i,n+=i}return t}read_unaligned_bytes(e){let t=Buffer.alloc(e);for(let n=0;n<e;n++)t[n]=this.read_bits(8);return t}};var z=class{_buffer;_typeinfos;constructor(e,t){this._buffer=new $(e),this._typeinfos=t}instance(e){if(e>=this._typeinfos.length)throw new U(`Invalid typeid ${e}`);let t=this._typeinfos[e],n=t[0],i=t[1]||[],a=this[n];if(typeof a!="function")throw new Error(`Decoder method ${n} not implemented`);return a.apply(this,i)}byte_align(){this._buffer.byte_align()}done(){return this._buffer.done()}used_bits(){return this._buffer.used_bits()}_array(e,t){let n=this._int(e),i=new Array(n);for(let a=0;a<n;a++)i[a]=this.instance(t);return i}_bitarray(e){let t=this._int(e);return[t,this._buffer.read_bits(t)]}_blob(e){let t=this._int(e);return this._buffer.read_aligned_bytes(t)}_bool(){return this._int([0,1])!==0}_choice(e,t){let n=this._int(e);if(!(n in t))throw new U(`Choice tag ${n} not found`);let i=t[n];return{[i[0]]:this.instance(i[1])}}_fourcc(){let e=this._buffer.read_bits(32),t=Buffer.alloc(4);return t.writeUInt32BE(e,0),t.toString("ascii")}_int(e){return e[0]+this._buffer.read_bits(e[1])}_null(){return null}_optional(e){return this._bool()?this.instance(e):null}_real32(){return this._buffer.read_unaligned_bytes(4).readFloatBE(0)}_real64(){return this._buffer.read_unaligned_bytes(8).readDoubleBE(0)}_struct(e){let t={};for(let n of e)if(n[0]==="__parent"){let i=this.instance(n[1]);if(typeof i=="object"&&i!==null&&!Array.isArray(i)&&!Buffer.isBuffer(i))t={...t,...i};else{if(e.length===1)return i;t[n[0]]=i}}else t[n[0]]=this.instance(n[1]);return t}},P=class{_buffer;_typeinfos;constructor(e,t){this._buffer=new $(e),this._typeinfos=t}instance(e){if(e>=this._typeinfos.length)throw new U(`Invalid typeid ${e}`);let t=this._typeinfos[e],n=t[0],i=t[1]||[],a=this[n];if(typeof a!="function")throw new Error(`Decoder method ${n} not implemented`);return a.apply(this,i)}byte_align(){this._buffer.byte_align()}done(){return this._buffer.done()}used_bits(){return this._buffer.used_bits()}_expect_skip(e){if(this._buffer.read_bits(8)!==e)throw new U(`Expected skip ${e}`)}_vint(){let e=this._buffer.read_bits(8),t=(e&1)!==0,n=BigInt(e>>1&63),i=6n;for(;(e&128)!==0;)e=this._buffer.read_bits(8),n|=BigInt(e&127)<<i,i+=7n;let a=t?-n:n;return a>=BigInt(Number.MIN_SAFE_INTEGER)&&a<=BigInt(Number.MAX_SAFE_INTEGER)?Number(a):a}_array(e,t){this._expect_skip(0);let n=Number(this._vint()),i=new Array(n);for(let a=0;a<n;a++)i[a]=this.instance(t);return i}_bitarray(e){this._expect_skip(1);let t=Number(this._vint());return[t,this._buffer.read_aligned_bytes(Math.floor((t+7)/8))]}_blob(e){this._expect_skip(2);let t=Number(this._vint());return this._buffer.read_aligned_bytes(t)}_bool(){return this._expect_skip(6),this._buffer.read_bits(8)!==0}_choice(e,t){this._expect_skip(3);let n=Number(this._vint());if(!(n in t))return this._skip_instance(),{};let i=t[n];return{[i[0]]:this.instance(i[1])}}_fourcc(){return this._expect_skip(7),this._buffer.read_aligned_bytes(4)}_int(e){return this._expect_skip(9),Number(this._vint())}_null(){return null}_optional(e){return this._expect_skip(4),this._buffer.read_bits(8)!==0?this.instance(e):null}_real32(){return this._expect_skip(7),this._buffer.read_aligned_bytes(4).readFloatBE(0)}_real64(){return this._expect_skip(8),this._buffer.read_aligned_bytes(8).readDoubleBE(0)}_struct(e){this._expect_skip(5);let t={},n=Number(this._vint());for(let i=0;i<n;i++){let a=Number(this._vint()),o=e.find(s=>s[2]===a);if(o)if(o[0]==="__parent"){let s=this.instance(o[1]);typeof s=="object"&&s!==null&&!Array.isArray(s)&&!Buffer.isBuffer(s)?t={...t,...s}:e.length===1?t=s:t[o[0]]=s}else t[o[0]]=this.instance(o[1]);else this._skip_instance()}return t}_skip_instance(){let e=this._buffer.read_bits(8);if(e===0){let t=Number(this._vint());for(let n=0;n<t;n++)this._skip_instance()}else if(e===1){let t=Number(this._vint());this._buffer.read_aligned_bytes(Math.floor((t+7)/8))}else if(e===2){let t=Number(this._vint());this._buffer.read_aligned_bytes(t)}else if(e===3)this._vint(),this._skip_instance();else if(e===4)this._buffer.read_bits(8)!==0&&this._skip_instance();else if(e===5){let t=Number(this._vint());for(let n=0;n<t;n++)this._vint(),this._skip_instance()}else e===6?this._buffer.read_aligned_bytes(1):e===7?this._buffer.read_aligned_bytes(4):e===8?this._buffer.read_aligned_bytes(8):e===9&&this._vint()}};var F=J(require("fs")),A=J(require("path"));function lt(){let r=[];try{r.push(A.default.resolve(__dirname,"..","protocols")),r.push(A.default.resolve(__dirname,"..","..","protocols"))}catch{}r.push(A.default.resolve(process.cwd(),"protocols"));let e=process.cwd();for(;e!==A.default.dirname(e);){let t=A.default.join(e,"node_modules","@astefanski","storm-parser","protocols");r.push(t),e=A.default.dirname(e)}for(let t of r)if(F.default.existsSync(t)&&F.default.readdirSync(t).some(n=>n.endsWith(".json")))return t;throw new Error(`@astefanski/storm-parser: Protocols directory not found. Did postinstall run? Try: npx tsx node_modules/@astefanski/storm-parser/scripts/postinstall.ts
|
|
3
|
+
Searched: `+r.join(", "))}var ce=new Map,le=null;function Me(){return le||(le=lt()),le}function re(r){if(ce.has(r))return ce.get(r);let e=Me(),t=A.default.join(e,`protocol${r}.json`);if(!F.default.existsSync(t))return null;let n=JSON.parse(F.default.readFileSync(t,"utf-8"));return ce.set(r,n),n}function ne(){let r=Me();return F.default.readdirSync(r).filter(e=>/^protocol\d+\.json$/.test(e)).map(e=>parseInt(e.match(/\d+/)[0],10)).sort((e,t)=>e-t)}var M=class{mpq;header;build=0;protocol;baseProtocol;constructor(e){e&&(this.mpq=new te(e,!1))}init(){let e=re(29406);if(!e)throw new Error("Base protocol29406 not found. Did postinstall run? Try: npx tsx node_modules/@astefanski/storm-parser/scripts/postinstall.ts");this.baseProtocol=e;let t=this.mpq.header.userDataHeader;if(!t||!t.content)throw new Error("Replay does not have a user data header");let n=new P(t.content,this.baseProtocol.typeinfos);this.header=n.instance(this.baseProtocol.replay_header_typeid),this.build=this.header.m_version.m_baseBuild,this.protocol=this.loadProtocolForBuild(this.build)}loadProtocolForBuild(e){let t=re(e);if(!t){let n=ne(),i=n[0];for(let a of n)a<=e&&a>i&&(i=a);t=re(i)}if(!t)throw new Error(`No protocol found for build ${e}`);return t}*decodeEventStream(e,t,n,i){if(!this.protocol)throw new Error("Protocol not loaded");let a=0;for(;!e.done();){let o=e.used_bits(),s=e.instance(this.protocol.svaruint32_typeid),c=Object.keys(s)[0],l=s[c];a+=l;let f=i?e.instance(this.protocol.replay_userid_typeid):void 0,u=Number(e.instance(t)),m=n[u];if(!m)throw new Error(`Unknown eventid(${u})`);let b=m[0],d=m[1],h=e.instance(b);h._event=d,h._eventid=u,h._gameloop=a,i&&(h._userid=f),e.byte_align(),h._bits=e.used_bits()-o,yield h}}getDetails(){if(!this.protocol)throw new Error("Protocol not loaded");let e=this.mpq.readFile("replay.details");return e?new P(e,this.protocol.typeinfos).instance(this.protocol.game_details_typeid):null}getInitData(){if(!this.protocol)throw new Error("Protocol not loaded");let e=this.mpq.readFile("replay.initData");return e?new z(e,this.protocol.typeinfos).instance(this.protocol.replay_initdata_typeid):null}getTrackerEvents(){if(!this.protocol)throw new Error("Protocol not loaded");let e=this.mpq.readFile("replay.tracker.events");if(!e)return[];let t=new P(e,this.protocol.typeinfos);return Array.from(this.decodeEventStream(t,this.protocol.tracker_eventid_typeid,this.protocol.tracker_event_types,!1))}getGameEvents(){if(!this.protocol)throw new Error("Protocol not loaded");let e=this.mpq.readFile("replay.game.events");if(!e)return[];let t=new z(e,this.protocol.typeinfos);return Array.from(this.decodeEventStream(t,this.protocol.game_eventid_typeid,this.protocol.game_event_types,!0))}getAttributeEvents(){if(!this.protocol)throw new Error("Protocol not loaded");let e=this.mpq.readFile("replay.attributes.events");return e?new P(e,this.protocol.typeinfos).instance(this.protocol.replay_attributes_events_typeid):null}extractFile(e){return this.mpq.readFile(e)}getHeader(){return this.header}getBuild(){return this.build}};var ie=class extends M{constructor(e){super();let t=e;if(!t){let n=ne();t=n[n.length-1]}this.protocol=this.loadProtocolForBuild(t)}parseTracker(e){if(!this.protocol)return[];try{let t=new P(e,this.protocol.typeinfos);return Array.from(this.decodeEventStream(t,this.protocol.tracker_eventid_typeid,this.protocol.tracker_event_types,!1))}catch(t){return console.error("[LiveStreamParser] Failed to parse tracker events",t),[]}}parseGame(e){if(!this.protocol)return[];try{let t=new z(e,this.protocol.typeinfos);return Array.from(this.decodeEventStream(t,this.protocol.game_eventid_typeid,this.protocol.game_event_types,!0))}catch(t){return console.error("[LiveStreamParser] Failed to parse game events",t),[]}}parseDetails(e){if(!this.protocol)return null;try{return new P(e,this.protocol.typeinfos).instance(this.protocol.game_details_typeid)}catch(t){return console.error("[LiveStreamParser] Failed to parse details",t),null}}};var He=["Abathur","Alarak","Alexstrasza","Ana","Anduin","Anubarak","Artanis","Arthas","Auriel","Azmodan","Blaze","Brightwing","Cassia","Chen","Cho","Chromie","Deathwing","Deckard","Dehaka","Diablo","DVa","ETC","Falstad","Fenix","Gall","Garrosh","Gazlowe","Genji","Greymane","Guldan","Hanzo","Hogger","Illidan","Imperius","Jaina","Johanna","Junkrat","Kaelthas","KelThuzad","Kerrigan","Kharazim","Leoric","LiLi","LiMing","LtMorales","Lunara","Maiev","Malfurion","MalGanis","Malthael","Medivh","Mei","Mephisto","Muradin","Murky","Nazeebo","Nova","Orphea","Probius","Qhira","Ragnaros","Raynor","Rehgar","Rexxar","Samuro","SgtHammer","Sonya","Stitches","Stukov","Sylvanas","Tassadar","TheButcher","TheLostVikings","Thrall","Tracer","Tychus","Tyrael","Tyrande","Uther","Valeera","Valla","Varian","Whitemane","Xul","Yrel","Zagara","Zarya","Zeratul","Zuljin"],Le={FaerieDragon:"Brightwing",Amazon:"Cassia",Barbarian:"Sonya",Crusader:"Johanna",DemonHunter:"Valla",WitchDoctor:"Nazeebo",Monk:"Kharazim",Wizard:"LiMing",Tinker:"Gazlowe",Medic:"LtMorales",L90ETC:"ETC",Butcher:"TheButcher",LostVikings:"TheLostVikings",Necromancer:"Xul",Dryad:"Lunara",Shapeshifter:"Greymane",ChoGall:"Cho"};function q(r){if(!r)return null;if(He.includes(r))return r;if(Le[r])return Le[r];let e=r.replace(/[^a-zA-Z0-9]/g,"").toLowerCase(),t=He.find(n=>n.toLowerCase()===e);return t||null}var Oe={TownCannonTowerL2:"Fort Tower",TownCannonTowerL3:"Keep Tower",TownTownHallL2:"Fort",TownTownHallL3:"Keep",TownMoonwellL2:"Fort Well",TownMoonwellL3:"Keep Well"},ft={MercLanerMeleeKnight:"Bruiser Camp",MercLanerRangedMage:"Bruiser Camp",MercLanerSiegeGiant:"Siege Camp",MercLanerRangedMinion:"Siege Camp"};function B(r){return Buffer.isBuffer(r)?r.toString("utf8"):typeof r=="string"?r:String(r??"")}function v(r,e){if(!r)return;let t=r.find(n=>B(n.m_key)===e);return t!==void 0?t.m_value:void 0}function ae(r,e){if(!r)return;let t=r.find(n=>B(n.m_key)===e);return t!==void 0?B(t.m_value):void 0}function w(r,e){if(!r)return;let t=r.find(n=>B(n.m_key)===e);return t!==void 0?t.m_value:void 0}function fe(r,e){return`${r}-${e}`}function R(r,e){return(r-e)/16}function Ue(r,e,t){let n={playerIDMap:{},loopGameStart:0,loopGameEnd:0,unitIndex:{},heroUnits:{},heroLives:{}};t.bans||(t.bans={0:[],1:[]}),t.levelTimes={0:{},1:{}},t.takedowns=[],t.structures={},t.XPBreakdown=[],t.mercs={captures:[],units:{}},t.objective={0:{count:0,events:[]},1:{count:0,events:[]},type:t.map||""};for(let i of r)switch(n.loopGameEnd=Math.max(n.loopGameEnd,i._gameloop),i._event){case"NNet.Replay.Tracker.SStatGameEvent":dt(i,n,e,t);break;case"NNet.Replay.Tracker.SHeroBannedEvent":if(i.m_hero){let a=B(i.m_hero),o=q(a);if(!o)break;let s=i.m_controllingTeam===2?1:0;if(t.bans&&t.bans[s]){let c=t.bans[s].length+1,l=t.bans[0].length+t.bans[1].length+1;t.bans[s].push({hero:o,order:c,absolute:l})}}break;case"NNet.Replay.Tracker.SUnitBornEvent":pt(i,n,t);break;case"NNet.Replay.Tracker.SUnitDiedEvent":bt(i,n,t);break;case"NNet.Replay.Tracker.SUnitOwnerChangeEvent":ht(i,n);break}return t.loopGameStart=n.loopGameStart,t.loopLength=n.loopGameEnd,t.length=(n.loopGameEnd-n.loopGameStart)/16,_t(n,e),{playerIDMap:n.playerIDMap}}function dt(r,e,t,n){let i=B(r.m_eventName),a=r.m_intData,o=r.m_stringData,s=r.m_fixedData;switch(i){case"PlayerInit":{let c=v(a,"PlayerID"),l=ae(o,"ToonHandle");c!==void 0&&l&&t[l]&&(e.playerIDMap[c]=l);break}case"GatesOpen":e.loopGameStart=r._gameloop;break;case"LevelUp":{let c=v(a,"PlayerID"),l=v(a,"Level");if(c===void 0||l===void 0)break;let f;if(c>=1&&c<=5)f="0";else if(c>=6&&c<=10)f="1";else break;n.levelTimes[f][String(l)]||(n.levelTimes[f][String(l)]={loop:r._gameloop,level:l,team:f,time:R(r._gameloop,e.loopGameStart)});break}case"TalentChosen":{let c=v(a,"PlayerID"),l=ae(o,"PurchaseName");if(c===void 0||!l||l==="Win"||l==="Loss"||l.startsWith("Hero"))break;let f=n.map?.replace(/\s+/g,"")||"";if(l===f)break;let u=e.playerIDMap[c];if(!u||!t[u])break;let m=["Tier1Choice","Tier2Choice","Tier3Choice","Tier4Choice","Tier5Choice","Tier6Choice","Tier7Choice"];for(let b of m)if(!t[u].talents[b]){t[u].talents[b]=l;break}break}case"PlayerDeath":{let c=v(a,"PlayerID"),l=v(a,"KillingPlayer"),f=w(s,"PositionX")??0,u=w(s,"PositionY")??0;if(c===void 0)break;let m=e.playerIDMap[c];if(!m)break;let b={player:m,hero:t[m]?.hero||""},d=[],h=t[m]?.team;if(l&&l>0){let _=e.playerIDMap[l];_&&t[_]&&d.push({player:_,hero:t[_].hero})}for(let[_,y]of Object.entries(e.playerIDMap)){let x=t[y];!x||x.team===h||parseInt(_)===l||d.push({player:y,hero:x.hero})}let p={loop:r._gameloop,time:R(r._gameloop,e.loopGameStart),x:f,y:u,killers:d,victim:b};n.takedowns.push(p),t[m]&&t[m].deaths.push(p);for(let _ of d)t[_.player]&&t[_.player].takedowns.push(p);break}case"PeriodicXPBreakdown":{let c=v(a,"Team");if(c===void 0)break;let l={GameTime:v(a,"GameTime")??0,PreviousGameTime:v(a,"PreviousGameTime")??0,MinionXP:w(s,"MinionXP")??0,CreepXP:w(s,"CreepXP")??0,StructureXP:w(s,"StructureXP")??0,HeroXP:w(s,"HeroXP")??0,TrickleXP:w(s,"TrickleXP")??0};n.XPBreakdown.push({loop:r._gameloop,time:R(r._gameloop,e.loopGameStart),team:c,teamLevel:v(a,"TeamLevel")??0,breakdown:l,theoreticalMinionXP:v(a,"TheoreticalMinionXP")??0});break}case"EndOfGameXPBreakdown":{let c=v(a,"Team");if(c===void 0)break;n.XPBreakdown.push({loop:r._gameloop,time:R(r._gameloop,e.loopGameStart),team:c,theoreticalMinionXP:v(a,"TheoreticalMinionXP")??0,breakdown:{GameTime:0,PreviousGameTime:0,MinionXP:w(s,"MinionXP")??0,CreepXP:w(s,"CreepXP")??0,StructureXP:w(s,"StructureXP")??0,HeroXP:w(s,"HeroXP")??0,TrickleXP:w(s,"TrickleXP")??0}});break}case"JungleCampCapture":{let c=v(a,"CampTeam")??v(a,"Team")??0;n.mercs.captures.push({loop:r._gameloop,type:ae(o,"CampType")??ae(o,"Result")??"Unknown Camp",team:c,time:R(r._gameloop,e.loopGameStart)});break}case"EndOfGameTalentChoices":{let c=v(a,"PlayerID");if(c===void 0)break;let l=e.playerIDMap[c];if(!l||!t[l])break;let f={};if(o)for(let u of o){let m=B(u.m_key),b=B(u.m_value);m==="Tier 1 Choice"&&b?f.Tier1Choice=b:m==="Tier 2 Choice"&&b?f.Tier2Choice=b:m==="Tier 3 Choice"&&b?f.Tier3Choice=b:m==="Tier 4 Choice"&&b?f.Tier4Choice=b:m==="Tier 5 Choice"&&b?f.Tier5Choice=b:m==="Tier 6 Choice"&&b?f.Tier6Choice=b:m==="Tier 7 Choice"&&b&&(f.Tier7Choice=b)}t[l].talents=f;break}default:mt(i,r,e,n,a,s);break}}var ut=new Set(["SoulEatersSpawned","TributeCollected","RavenCurseActivated","AltarCaptured","SkyTempleShotsFired","DragonKnightActivated","GardenTerrorActivated","InfernalShrineCaptured","PunisherKilled","VolskayaVehicleCapture","BraxisWaveStart","ImmortalDefeated","NukeExploded","PayloadDelivered","AlteracCavalryCharge","AlteracCavalry"]);function mt(r,e,t,n,i,a){if(!ut.has(r)||!i)return;let o=v(i,"Team")??v(i,"Event")??0,s=o===0||o===1?o:0,c={team:o,loop:e._gameloop,time:R(e._gameloop,t.loopGameStart),score:v(i,"Score"),duration:w(a,"Duration")};n.objective[s].events.push(c),n.objective[s].count=n.objective[s].events.length}function pt(r,e,t){let n=B(r.m_unitTypeName),i=r.m_unitTagIndex,a=r.m_unitTagRecycle,o=fe(i,a),s=r.m_controlPlayerId??r.m_upkeepPlayerId,c=r.m_x??0,l=r.m_y??0,f;if(s>=1&&s<=5?f=0:s>=6&&s<=10?f=1:s===11?f=0:s===12?f=1:f=s<=5?0:1,e.unitIndex[o]={type:n,playerId:s,team:f,x:c,y:l,bornLoop:r._gameloop},n.startsWith("Town")&&Oe[n]&&(t.structures[o]={type:n,name:Oe[n],tag:i,rtag:a,x:c,y:l,team:f}),n.startsWith("Hero")&&s>=1&&s<=10){e.heroUnits[o]=s,e.heroLives[s]||(e.heroLives[s]=[]);let u=R(r._gameloop,e.loopGameStart);e.heroLives[s].push({born:u,locations:[{x:c,y:l,time:u}],duration:0})}if(ft[n]){let m=t.mercs.captures[t.mercs.captures.length-1]?.loop??r._gameloop;t.mercs.units[o]={loop:m,team:f,type:n,locations:[{x:c,y:l}],time:R(m,e.loopGameStart),duration:0}}}function bt(r,e,t){let n=fe(r.m_unitTagIndex,r.m_unitTagRecycle),i=R(r._gameloop,e.loopGameStart);t.structures[n]&&(t.structures[n].destroyedLoop=r._gameloop,t.structures[n].destroyed=i),t.mercs.units[n]&&(t.mercs.units[n].duration=i-t.mercs.units[n].time);let a=e.heroUnits[n];if(a!==void 0&&e.heroLives[a]){let o=e.heroLives[a],s=o[o.length-1];s&&s.died===void 0&&(s.died=i,s.duration=i-s.born)}}function ht(r,e){let t=fe(r.m_unitTagIndex,r.m_unitTagRecycle),n=r.m_controlPlayerId??r.m_upkeepPlayerId;e.unitIndex[t]&&(e.unitIndex[t].playerId=n,n>=1&&n<=5?e.unitIndex[t].team=0:n>=6&&n<=10&&(e.unitIndex[t].team=1))}function _t(r,e){for(let[t,n]of Object.entries(r.heroLives)){let i=parseInt(t,10),a=r.playerIDMap[i];if(!a||!e[a])continue;for(let s of n)if(s.died===void 0){let c=s.locations[s.locations.length-1];s.duration=c?c.time-s.born:0}let o="";for(let[s,c]of Object.entries(r.heroUnits))if(c===i){o=s;break}o&&(e[a].units[o]={lives:n})}}var gt=["DamageTaken","CreepDamage","Healing","HeroDamage","MinionDamage","SelfHealing","SiegeDamage","ProtectionGivenToAllies","TeamfightDamageTaken","TeamfightHealingDone","TeamfightHeroDamage","TimeCCdEnemyHeroes","TimeRootingEnemyHeroes","TimeSpentDead","TimeStunningEnemyHeroes","TimeSilencingEnemyHeroes"];function yt(){return{DamageTaken:0,CreepDamage:0,Healing:0,HeroDamage:0,MinionDamage:0,SelfHealing:0,SiegeDamage:0,ProtectionGivenToAllies:0,TeamfightDamageTaken:0,TeamfightHealingDone:0,TeamfightHeroDamage:0,TimeCCdEnemyHeroes:0,TimeRootingEnemyHeroes:0,TimeSpentDead:0,TimeStunningEnemyHeroes:0,TimeSilencingEnemyHeroes:0,avgTimeSpentDead:0,timeDeadPct:0}}function xt(){return{mercCaptures:0,mercUptime:0,mercUptimePercent:0,structures:{},KDA:0,PPK:0,timeTo10:0,totals:yt(),levelAdvTime:0,maxLevelAdv:0,avgLevelAdv:0,levelAdvPct:0,uptime:[],uptimeHistogram:{},wipes:0,avgHeroesAlive:0,aces:0,timeWithHeroAdv:0,pctWithHeroAdv:0,passiveXPRate:0,passiveXPDiff:0,passiveXPGain:0}}function Ne(r,e){St(r),vt(r,e),kt(r,e),wt(r),Et(r,e),Dt(r)}function vt(r,e){for(let t of["0","1"]){let n=r.teams[t];if(!n)continue;n.names=[],n.heroes=[],n.tags=[],n.stats=xt();for(let u of n.ids){let m=e[u];m&&(n.names.push(m.name),n.heroes.push(m.hero),n.tags.push(m.tag))}for(let u of n.ids){let m=e[u];if(m)for(let b of gt){let d=m.gameStats[b];typeof d=="number"&&(n.stats.totals[b]+=d)}}let i=n.ids.reduce((u,m)=>u+(e[m]?.gameStats.Deaths??0),0);i>0&&(n.stats.totals.avgTimeSpentDead=n.stats.totals.TimeSpentDead/i),r.length>0&&(n.stats.totals.timeDeadPct=n.stats.totals.TimeSpentDead/(r.length*n.ids.length));let a=n.takedowns,o=i;n.stats.KDA=o>0?a/o:a,n.stats.PPK=a>0?r.takedowns.filter(u=>n.ids.includes(u.killers[0]?.player)).reduce((u,m)=>u+m.killers.length,0)/a:0;let s=r.levelTimes[t];s?.["10"]&&(n.stats.timeTo10=s[10].time);let c=parseInt(t,10),l=r.mercs.captures.filter(u=>u.team===c);n.stats.mercCaptures=l.length;let f=0;for(let u of Object.values(r.mercs.units))u.team===c&&u.duration>0&&(f+=u.duration);n.stats.mercUptime=f,n.stats.mercUptimePercent=r.length>0?f/r.length:0,Tt(r,n,t)}}function Tt(r,e,t){let n=parseInt(t,10),i=n===0?1:0,a={};for(let o of Object.values(r.structures)){let s=o.name;a[s]||(a[s]={lost:0,destroyed:0,first:r.length}),o.team===i&&o.destroyed!==void 0&&(a[s].destroyed++,a[s].first=Math.min(a[s].first,o.destroyed)),o.team===n&&o.destroyed!==void 0&&a[s].lost++}e.stats.structures=a}function kt(r,e){let t=r.length/60;for(let n of Object.values(e)){let i=n.gameStats,a=i.Deaths??0,o=i.TeamTakedowns??0;t>0&&(i.DPM=(i.HeroDamage??0)/t,i.HPM=((i.Healing??0)+(i.SelfHealing??0))/t,i.XPM=(i.ExperienceContribution??0)/t),i.KDA=a>0?(i.Takedowns??0)/a:i.Takedowns??0,i.KillParticipation=o>0?(i.Takedowns??0)/o:0,i.damageDonePerDeath=a>0?(i.HeroDamage??0)/a:i.HeroDamage??0,i.damageTakenPerDeath=a>0?(i.DamageTaken??0)/a:i.DamageTaken??0,i.healingDonePerDeath=a>0?((i.Healing??0)+(i.SelfHealing??0))/a:(i.Healing??0)+(i.SelfHealing??0),i.length=r.length}}function St(r){let e=0,t=0,n=new Set(r.teams[0]?.ids||[]);for(let i of r.takedowns)n.has(i.victim.player)?t++:e++;r.team0Takedowns=e,r.team1Takedowns=t,r.teams[0]&&(r.teams[0].takedowns=e),r.teams[1]&&(r.teams[1].takedowns=t)}function wt(r){let e=r.levelTimes[0]||{},t=r.levelTimes[1]||{},n=[];for(let l of Object.values(e))n.push({time:l.time,team:0,level:l.level});for(let l of Object.values(t))n.push({time:l.time,team:1,level:l.level});if(n.sort((l,f)=>l.time-f.time),n.length===0){r.levelAdvTimeline=[];return}let i=[],a=0,o=0,s=n[0].time;for(let l of n){let f=a-o;l.time>s&&i.push({start:s,end:l.time,levelDiff:f,length:l.time-s}),l.team===0?a=l.level:o=l.level,s=l.time}let c=a-o;r.length>s&&i.push({start:s,end:r.length,levelDiff:c,length:r.length-s}),r.levelAdvTimeline=i;for(let l of["0","1"]){let f=r.teams[l];if(!f)continue;let u=l==="0"?1:-1,m=0,b=0,d=0,h=0;for(let p of i){let _=p.levelDiff*u;_>0&&(m+=p.length),b=Math.max(b,_),d+=_*p.length,h+=p.length}f.stats.levelAdvTime=m,f.stats.maxLevelAdv=b,f.stats.avgLevelAdv=h>0?d/h:0,f.stats.levelAdvPct=r.length>0?m/r.length:0}}function Et(r,e){for(let a of["0","1"]){let o=r.teams[a];if(!o)continue;let s=[];for(let p of o.ids){let _=e[p];if(_)for(let y of _.deaths){s.push({time:y.time,delta:-1});let x=y.time+Pt(_.gameStats.Level??1);x<r.length&&s.push({time:x,delta:1})}}s.sort((p,_)=>p.time-_.time);let c=[{time:0,heroes:o.ids.length}],l=o.ids.length;for(let p of s)l+=p.delta,l=Math.max(0,Math.min(o.ids.length,l)),c.push({time:p.time,heroes:l});o.stats.uptime=c;let f={};for(let p=0;p<c.length;p++){let y=(p<c.length-1?c[p+1].time:r.length)-c[p].time,x=String(c[p].heroes);f[x]=(f[x]||0)+y}o.stats.uptimeHistogram=f;let u=0,m=0;for(let p=0;p<c.length;p++){let y=(p<c.length-1?c[p+1].time:r.length)-c[p].time;u+=c[p].heroes*y,m+=y}o.stats.avgHeroesAlive=m>0?u/m:o.ids.length,o.stats.wipes=c.filter(p=>p.heroes===0).length,o.stats.aces=0;let b=a==="0"?"1":"0",d=r.teams[b];d?.stats?.uptime&&(o.stats.aces=d.stats.uptime.filter(p=>p.heroes===0).length);let h=r.XPBreakdown.filter(p=>p.team===parseInt(a,10));if(h.length>0){let _=h[h.length-1].breakdown.TrickleXP;o.stats.passiveXPGain=_,o.stats.passiveXPRate=r.length>0?_/(r.length/60):0}}for(let a of["0","1"]){let o=r.teams[a],s=a==="0"?"1":"0",c=r.teams[s];if(!o||!c)continue;let l=o.stats.uptime,f=c.stats.uptime;if(!l.length||!f.length)continue;let u=new Set;for(let d of l)u.add(d.time);for(let d of f)u.add(d.time);let m=Array.from(u).sort((d,h)=>d-h),b=0;for(let d=0;d<m.length;d++){let h=m[d],_=(d<m.length-1?m[d+1]:r.length)-h,y=ze(l,h),x=ze(f,h);y>x&&(b+=_)}o.stats.timeWithHeroAdv=b,o.stats.pctWithHeroAdv=r.length>0?b/r.length:0}let t=r.teams[0]?.stats.passiveXPRate??0,n=r.teams[1]?.stats.passiveXPRate??0,i=(t+n)/2;r.teams[0]&&(r.teams[0].stats.passiveXPDiff=i>0?t/i:0),r.teams[1]&&(r.teams[1].stats.passiveXPDiff=i>0?n/i:0)}function ze(r,e){let t=0;for(let n of r)if(n.time<=e)t=n.heroes;else break;return t}function Pt(r){return r<=1?15:r<=5?15+(r-1)*2:r<=10?23+(r-5)*3:r<=15?38+(r-10)*4:58+(r-15)*5}function Dt(r){let e=1/0,t=-1,n=1/0,i=-1;for(let o of Object.values(r.structures))o.destroyed!==void 0&&(o.name==="Fort"&&o.destroyed<e&&(e=o.destroyed,t=o.team===0?1:0),o.name==="Keep"&&o.destroyed<n&&(n=o.destroyed,i=o.team===0?1:0));t>=0&&(r.firstFort=t,r.firstFortWin=t===r.winner),i>=0&&(r.firstKeep=i,r.firstKeepWin=i===r.winner);let a=[...r.objective[0].events.map(o=>({...o,assignedTeam:0})),...r.objective[1].events.map(o=>({...o,assignedTeam:1}))].sort((o,s)=>o.loop-s.loop);a.length>0&&(r.firstObjective=a[0].assignedTeam,r.firstObjectiveWin=a[0].assignedTeam===r.winner),r.firstPickWin=r.picks.first===r.winner}function k(r){return Buffer.isBuffer(r)?r.toString("utf8"):typeof r=="string"?r:String(r??"")}var oe=class{static async analyze(e){try{let t=new M(e);await t.init();let n=t.getDetails();if(!n)throw new Error("Missing replay.details from parsed MPQ archive");let i=t.getTrackerEvents(),a=t.getInitData(),s=t.getHeader()?.m_version??{},c={m_flags:s.m_flags??0,m_major:s.m_major??0,m_minor:s.m_minor??0,m_revision:s.m_revision??0,m_build:s.m_baseBuild??t.getBuild(),m_baseBuild:s.m_baseBuild??t.getBuild()},l=n.m_playerList.find(b=>b?.m_toon)?.m_toon,f={version:c,map:k(n.m_title),isBlizzardMap:n.m_isBlizzardMap,timeLocalOffset:Number(n.m_timeLocalOffset),gameSpeed:n.m_gameSpeed,date:this.fileTimeToDate(n.m_timeUTC).toISOString(),rawDate:Number(n.m_timeUTC),length:0,winner:-1,region:l?.m_region,playerIDs:[],heroes:[],levelTimes:{0:{},1:{}},bans:{0:[],1:[]},picks:{0:[],1:[],first:0},XPBreakdown:[],takedowns:[],mercs:{captures:[],units:{}},team0Takedowns:0,team1Takedowns:0,structures:{},objective:{0:{count:0,events:[]},1:{count:0,events:[]},type:""},teams:{0:this.emptyTeam(),1:this.emptyTeam()},winningPlayers:[],levelAdvTimeline:[],firstPickWin:!1};f.objective.type=f.map||"";let u={};for(let b of n.m_playerList){if(!b?.m_toon)continue;let d=b.m_toon,h=k(d.m_programId),p=`${d.m_region}-${h}-${d.m_realm}-${d.m_id}`,_=k(b.m_hero),y=q(_)||_;u[p]={hero:y,name:k(b.m_name),uuid:d.m_id,region:d.m_region,realm:d.m_realm,ToonHandle:p,tag:0,team:b.m_teamId,win:b.m_result===1,skin:"",mount:"",banner:"",spray:"",clanTag:"",highestLeague:0,combinedRaceLevels:0,randomSeed:0,announcer:"",silenced:!1,voiceSilenced:!1,gameStats:{},awards:[],talents:{},takedowns:[],deaths:[],units:{}},f.playerIDs.push(p),f.heroes.push(y)}this.extractBattleTags(t,n,u),this.extractDraft(a,f,n),this.extractCosmetics(a,n,u);let{playerIDMap:m}=Ue(i,u,f);this.processScoreEvents(i,m,u);for(let[b,d]of Object.entries(u)){d.win&&(f.winner=d.team,f.winningPlayers.push(b));let h=f.teams[d.team.toString()];h&&(h.level=Math.max(h.level,d.gameStats.Level||0),h.ids.push(b))}return Ne(f,u),{status:1,match:f,players:u}}catch(t){return console.error("ReplayAnalyzer Error:",t),{status:-2,error:String(t)}}}static emptyTeam(){return{level:0,takedowns:0,ids:[],names:[],heroes:[],tags:[],stats:{mercCaptures:0,mercUptime:0,mercUptimePercent:0,structures:{},KDA:0,PPK:0,timeTo10:0,totals:{DamageTaken:0,CreepDamage:0,Healing:0,HeroDamage:0,MinionDamage:0,SelfHealing:0,SiegeDamage:0,ProtectionGivenToAllies:0,TeamfightDamageTaken:0,TeamfightHealingDone:0,TeamfightHeroDamage:0,TimeCCdEnemyHeroes:0,TimeRootingEnemyHeroes:0,TimeSpentDead:0,TimeStunningEnemyHeroes:0,TimeSilencingEnemyHeroes:0,avgTimeSpentDead:0,timeDeadPct:0},levelAdvTime:0,maxLevelAdv:0,avgLevelAdv:0,levelAdvPct:0,uptime:[],uptimeHistogram:{},wipes:0,avgHeroesAlive:0,aces:0,timeWithHeroAdv:0,pctWithHeroAdv:0,passiveXPRate:0,passiveXPDiff:0,passiveXPGain:0}}}static extractBattleTags(e,t,n){let i=e.extractFile("replay.server.battlelobby");if(i)try{let a=new RegExp("([\\p{L}\\d]{3,24}#\\d{4,10})[z\xD8]?","gu"),o=i.toString("utf8").match(a);if(!o)return;let s=0;for(let c of t.m_playerList){if(!c?.m_toon)continue;let l=k(c.m_name);for(;s<o.length;){let u=o[s].split("#"),m=u[0],b=u[1].replace(/[zØ]/g,"");if(s++,m===l){let d=c.m_toon,h=`${d.m_region}-${k(d.m_programId)}-${d.m_realm}-${d.m_id}`;n[h]&&(n[h].tag=parseInt(b,10)||0);break}}}}catch(a){console.error("BattleTag regex error:",a)}}static extractDraft(e,t,n){if(e)try{let i=e.m_syncLobbyState;if(!i)return;let a=i.m_lobbyState,o=i.m_gameDescription;if(!a)return;o&&(t.randomValue=o.m_randomValue,t.gameOptions=o.m_gameOptions);let s=[],c=[];for(let d of n.m_playerList){if(!d?.m_toon)continue;let h=k(d.m_hero),p=q(h)||h;d.m_teamId===0?s.push(p):d.m_teamId===1&&c.push(p)}t.picks={0:s,1:c,first:0};let l,f=o?.m_gameOptions;if(f&&typeof f.m_ammId=="number"){let d=f.m_ammId;d===50001?l="Quick Match":d===50031?l="ARAM":d===50041?l="Unranked Draft":d===50051?l="Custom":d===50061?l="Hero League":d===50071?l="Team League":d===50091&&(l="Storm League")}if(!l&&typeof a.m_gameMode=="number"){let d=a.m_gameMode;d===3?l="Quick Match":d===4?l="Custom":d===5?l="Hero League":d===6?l="Team League":d===7?l="Unranked Draft":d===8&&(l="ARAM")}if(t.mode=l,typeof a.m_gameType=="number"&&(t.type=a.m_gameType),!a.m_slots)return;let m=a.m_pickedMapTag,b=0;m!==void 0&&(b=a.m_firstPickTeam??0,t.picks.first=b)}catch{}}static extractCosmetics(e,t,n){if(e)try{let i=e.m_syncLobbyState;if(!i)return;let a=i.m_lobbyState;if(!a)return;let o=a.m_slots,s=i.m_userInitialData;if(!o)return;let c=0;for(let l of t.m_playerList){if(!l?.m_toon)continue;let f=l.m_toon,u=`${f.m_region}-${k(f.m_programId)}-${f.m_realm}-${f.m_id}`,m=n[u];for(;c<o.length;){let b=o[c];c++;let d=b.m_hero;if(!(!d||Buffer.isBuffer(d)&&d.length===0)){if(m&&(m.skin=k(b.m_skin)||"",m.mount=k(b.m_mount)||"",m.announcer=k(b.m_announcerPack)||"",m.banner=k(b.m_banner)||"",m.spray=k(b.m_spray)||"",m.silenced=!!b.m_hasSilencePenalty,m.voiceSilenced=!!b.m_hasVoiceSilencePenalty,s)){let h=s.find(p=>k(p.m_name)===m.name);h&&(m.clanTag=k(h.m_clanTag),m.highestLeague=h.m_highestLeague,m.combinedRaceLevels=h.m_combinedRaceLevels,m.randomSeed=h.m_randomSeed)}break}}}}catch{}}static processScoreEvents(e,t,n){for(let i of e){if(i._event!=="NNet.Replay.Tracker.SScoreResultEvent")continue;let a=i.m_instanceList;for(let o of a){let s=k(o.m_name),c=o.m_values,l=s.startsWith("EndOfMatchAward"),f=0;for(let u of c)if(u&&u.length>0&&u[0]!==void 0){let m=f+1,b=t[m];if(b&&n[b]){let d=typeof u[0]=="object"&&u[0]!==null&&"m_value"in u[0]?u[0].m_value:u[0];d!=null&&(l?d===1&&n[b].awards.push(s):n[b].gameStats[s]=d)}f++}else u&&u.length===0&&f++}}}static fileTimeToDate(e){return new Date(Number(e)/1e4-116444736e5)}};0&&(module.exports={LiveStreamParser,ReplayAnalyzer,ReplayParser});
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var G=(r,e)=>()=>(e||r((e={exports:{}}).exports,e),e.exports);var pe=G((xt,me)=>{"use strict";var ue=[0,1,3,7,15,31,63,127,255],K=function(r){this.stream=r,this.bitOffset=0,this.curByte=0,this.hasByte=!1};K.prototype._ensureByte=function(){this.hasByte||(this.curByte=this.stream.readByte(),this.hasByte=!0)};K.prototype.read=function(r){for(var e=0;r>0;){this._ensureByte();var t=8-this.bitOffset;if(r>=t)e<<=t,e|=ue[t]&this.curByte,this.hasByte=!1,this.bitOffset=0,r-=t;else{e<<=r;var n=t-r;e|=(this.curByte&ue[r]<<n)>>n,this.bitOffset+=r,r=0}}return e};K.prototype.seek=function(r){var e=r%8,t=(r-e)/8;this.bitOffset=e,this.stream.seek(t),this.hasByte=!1};K.prototype.pi=function(){var r=new Buffer(6),e;for(e=0;e<r.length;e++)r[e]=this.read(8);return r.toString("hex")};me.exports=K});var he=G((vt,be)=>{"use strict";var H=function(){};H.prototype.readByte=function(){throw new Error("abstract method readByte() not implemented")};H.prototype.read=function(r,e,t){for(var n=0;n<t;){var i=this.readByte();if(i<0)return n===0?-1:n;r[e++]=i,n++}return n};H.prototype.seek=function(r){throw new Error("abstract method seek() not implemented")};H.prototype.writeByte=function(r){throw new Error("abstract method readByte() not implemented")};H.prototype.write=function(r,e,t){var n;for(n=0;n<t;n++)this.writeByte(r[e++]);return t};H.prototype.flush=function(){};be.exports=H});var ge=G((Tt,_e)=>{"use strict";_e.exports=(function(){var r=new Uint32Array([0,79764919,159529838,222504665,319059676,398814059,445009330,507990021,638119352,583659535,797628118,726387553,890018660,835552979,1015980042,944750013,1276238704,1221641927,1167319070,1095957929,1595256236,1540665371,1452775106,1381403509,1780037320,1859660671,1671105958,1733955601,2031960084,2111593891,1889500026,1952343757,2552477408,2632100695,2443283854,2506133561,2334638140,2414271883,2191915858,2254759653,3190512472,3135915759,3081330742,3009969537,2905550212,2850959411,2762807018,2691435357,3560074640,3505614887,3719321342,3648080713,3342211916,3287746299,3467911202,3396681109,4063920168,4143685023,4223187782,4286162673,3779000052,3858754371,3904687514,3967668269,881225847,809987520,1023691545,969234094,662832811,591600412,771767749,717299826,311336399,374308984,453813921,533576470,25881363,88864420,134795389,214552010,2023205639,2086057648,1897238633,1976864222,1804852699,1867694188,1645340341,1724971778,1587496639,1516133128,1461550545,1406951526,1302016099,1230646740,1142491917,1087903418,2896545431,2825181984,2770861561,2716262478,3215044683,3143675388,3055782693,3001194130,2326604591,2389456536,2200899649,2280525302,2578013683,2640855108,2418763421,2498394922,3769900519,3832873040,3912640137,3992402750,4088425275,4151408268,4197601365,4277358050,3334271071,3263032808,3476998961,3422541446,3585640067,3514407732,3694837229,3640369242,1762451694,1842216281,1619975040,1682949687,2047383090,2127137669,1938468188,2001449195,1325665622,1271206113,1183200824,1111960463,1543535498,1489069629,1434599652,1363369299,622672798,568075817,748617968,677256519,907627842,853037301,1067152940,995781531,51762726,131386257,177728840,240578815,269590778,349224269,429104020,491947555,4046411278,4126034873,4172115296,4234965207,3794477266,3874110821,3953728444,4016571915,3609705398,3555108353,3735388376,3664026991,3290680682,3236090077,3449943556,3378572211,3174993278,3120533705,3032266256,2961025959,2923101090,2868635157,2813903052,2742672763,2604032198,2683796849,2461293480,2524268063,2284983834,2364738477,2175806836,2238787779,1569362073,1498123566,1409854455,1355396672,1317987909,1246755826,1192025387,1137557660,2072149281,2135122070,1912620623,1992383480,1753615357,1816598090,1627664531,1707420964,295390185,358241886,404320391,483945776,43990325,106832002,186451547,266083308,932423249,861060070,1041341759,986742920,613929101,542559546,756411363,701822548,3316196985,3244833742,3425377559,3370778784,3601682597,3530312978,3744426955,3689838204,3819031489,3881883254,3928223919,4007849240,4037393693,4100235434,4180117107,4259748804,2310601993,2373574846,2151335527,2231098320,2596047829,2659030626,2470359227,2550115596,2947551409,2876312838,2788305887,2733848168,3165939309,3094707162,3040238851,2985771188]),e=function(){var t=4294967295;this.getCRC=function(){return~t>>>0},this.updateCRC=function(n){t=t<<8^r[(t>>>24^n)&255]},this.updateCRCRun=function(n,i){for(;i-- >0;)t=t<<8^r[(t>>>24^n)&255]}};return e})()});var ye=G((kt,Ue)=>{Ue.exports={name:"seek-bzip",version:"2.0.0",contributors:["C. Scott Ananian (http://cscott.net)","Eli Skeggs","Kevin Kwok","Rob Landley (http://landley.net)"],description:"a pure-JavaScript Node.JS module for random-access decoding bzip2 data",main:"./lib/index.js",repository:{type:"git",url:"https://github.com/cscott/seek-bzip.git"},license:"MIT",bin:{"seek-bunzip":"./bin/seek-bunzip","seek-table":"./bin/seek-bzip-table"},directories:{test:"test"},dependencies:{commander:"^6.0.0"},devDependencies:{fibers:"^5.0.0",mocha:"^8.1.0"},scripts:{test:"mocha"}}});var Pe=G((St,Ee)=>{"use strict";var ze=pe(),j=he(),ke=ge(),Se=ye(),Y=20,xe=258,ve=0,Ne=1,Fe=2,Xe=6,Ge=50,Ke="314159265359",je="177245385090",Te=function(r,e){var t=r[e],n;for(n=e;n>0;n--)r[n]=r[n-1];return r[0]=t,t},g={OK:0,LAST_BLOCK:-1,NOT_BZIP_DATA:-2,UNEXPECTED_INPUT_EOF:-3,UNEXPECTED_OUTPUT_EOF:-4,DATA_ERROR:-5,OUT_OF_MEMORY:-6,OBSOLETE_INPUT:-7,END_OF_BLOCK:-8},I={};I[g.LAST_BLOCK]="Bad file checksum";I[g.NOT_BZIP_DATA]="Not bzip data";I[g.UNEXPECTED_INPUT_EOF]="Unexpected input EOF";I[g.UNEXPECTED_OUTPUT_EOF]="Unexpected output EOF";I[g.DATA_ERROR]="Data error";I[g.OUT_OF_MEMORY]="Out of memory";I[g.OBSOLETE_INPUT]="Obsolete (pre 0.9.5) bzip format not supported.";var T=function(r,e){var t=I[r]||"unknown error";e&&(t+=": "+e);var n=new TypeError(t);throw n.errorCode=r,n},S=function(r,e){this.writePos=this.writeCurrent=this.writeCount=0,this._start_bunzip(r,e)};S.prototype._init_block=function(){var r=this._get_next_block();return r?(this.blockCRC=new ke,!0):(this.writeCount=-1,!1)};S.prototype._start_bunzip=function(r,e){var t=new Buffer(4);(r.read(t,0,4)!==4||String.fromCharCode(t[0],t[1],t[2])!=="BZh")&&T(g.NOT_BZIP_DATA,"bad magic");var n=t[3]-48;(n<1||n>9)&&T(g.NOT_BZIP_DATA,"level out of range"),this.reader=new ze(r),this.dbufSize=1e5*n,this.nextoutput=0,this.outputStream=e,this.streamCRC=0};S.prototype._get_next_block=function(){var r,e,t,n=this.reader,i=n.pi();if(i===je)return!1;i!==Ke&&T(g.NOT_BZIP_DATA),this.targetBlockCRC=n.read(32)>>>0,this.streamCRC=(this.targetBlockCRC^(this.streamCRC<<1|this.streamCRC>>>31))>>>0,n.read(1)&&T(g.OBSOLETE_INPUT);var a=n.read(24);a>this.dbufSize&&T(g.DATA_ERROR,"initial position out of bounds");var s=n.read(16),o=new Buffer(256),c=0;for(r=0;r<16;r++)if(s&1<<15-r){var l=r*16;for(t=n.read(16),e=0;e<16;e++)t&1<<15-e&&(o[c++]=l+e)}var f=n.read(3);(f<Fe||f>Xe)&&T(g.DATA_ERROR);var u=n.read(15);u===0&&T(g.DATA_ERROR);var m=new Buffer(256);for(r=0;r<f;r++)m[r]=r;var b=new Buffer(u);for(r=0;r<u;r++){for(e=0;n.read(1);e++)e>=f&&T(g.DATA_ERROR);b[r]=Te(m,e)}var d=c+2,h=[],p;for(e=0;e<f;e++){var _=new Buffer(d),y=new Uint16Array(Y+1);for(s=n.read(5),r=0;r<d;r++){for(;(s<1||s>Y)&&T(g.DATA_ERROR),!!n.read(1);)n.read(1)?s--:s++;_[r]=s}var x,P;for(x=P=_[0],r=1;r<d;r++)_[r]>P?P=_[r]:_[r]<x&&(x=_[r]);p={},h.push(p),p.permute=new Uint16Array(xe),p.limit=new Uint32Array(Y+2),p.base=new Uint32Array(Y+1),p.minLen=x,p.maxLen=P;var A=0;for(r=x;r<=P;r++)for(y[r]=p.limit[r]=0,s=0;s<d;s++)_[s]===r&&(p.permute[A++]=s);for(r=0;r<d;r++)y[_[r]]++;for(A=s=0,r=x;r<P;r++)A+=y[r],p.limit[r]=A-1,A<<=1,s+=y[r],p.base[r+1]=A-s;p.limit[P+1]=Number.MAX_VALUE,p.limit[P]=A+y[P]-1,p.base[x]=0}var N=new Uint32Array(256);for(r=0;r<256;r++)m[r]=r;var M=0,C=0,le=0,E,F=this.dbuf=new Uint32Array(this.dbufSize);for(d=0;;){for(d--||(d=Ge-1,le>=u&&T(g.DATA_ERROR),p=h[b[le++]]),r=p.minLen,e=n.read(r);r>p.maxLen&&T(g.DATA_ERROR),!(e<=p.limit[r]);r++)e=e<<1|n.read(1);e-=p.base[r],(e<0||e>=xe)&&T(g.DATA_ERROR);var X=p.permute[e];if(X===ve||X===Ne){M||(M=1,s=0),X===ve?s+=M:s+=2*M,M<<=1;continue}if(M)for(M=0,C+s>this.dbufSize&&T(g.DATA_ERROR),E=o[m[0]],N[E]+=s;s--;)F[C++]=E;if(X>c)break;C>=this.dbufSize&&T(g.DATA_ERROR),r=X-1,E=Te(m,r),E=o[E],N[E]++,F[C++]=E}for((a<0||a>=C)&&T(g.DATA_ERROR),e=0,r=0;r<256;r++)t=e+N[r],N[r]=e,e=t;for(r=0;r<C;r++)E=F[r]&255,F[N[E]]|=r<<8,N[E]++;var Z=0,fe=0,de=0;return C&&(Z=F[a],fe=Z&255,Z>>=8,de=-1),this.writePos=Z,this.writeCurrent=fe,this.writeCount=C,this.writeRun=de,!0};S.prototype._read_bunzip=function(r,e){var t,n,i;if(this.writeCount<0)return 0;for(var a=0,s=this.dbuf,o=this.writePos,c=this.writeCurrent,l=this.writeCount,f=this.outputsize,u=this.writeRun;l;){for(l--,n=c,o=s[o],c=o&255,o>>=8,u++===3?(t=c,i=n,c=-1):(t=1,i=c),this.blockCRC.updateCRCRun(i,t);t--;)this.outputStream.writeByte(i),this.nextoutput++;c!=n&&(u=0)}return this.writeCount=l,this.blockCRC.getCRC()!==this.targetBlockCRC&&T(g.DATA_ERROR,"Bad block CRC (got "+this.blockCRC.getCRC().toString(16)+" expected "+this.targetBlockCRC.toString(16)+")"),this.nextoutput};var ne=function(r){if("readByte"in r)return r;var e=new j;return e.pos=0,e.readByte=function(){return r[this.pos++]},e.seek=function(t){this.pos=t},e.eof=function(){return this.pos>=r.length},e},we=function(r){var e=new j,t=!0;if(r)if(typeof r=="number")e.buffer=new Buffer(r),t=!1;else{if("writeByte"in r)return r;e.buffer=r,t=!1}else e.buffer=new Buffer(16384);return e.pos=0,e.writeByte=function(n){if(t&&this.pos>=this.buffer.length){var i=new Buffer(this.buffer.length*2);this.buffer.copy(i),this.buffer=i}this.buffer[this.pos++]=n},e.getBuffer=function(){if(this.pos!==this.buffer.length){if(!t)throw new TypeError("outputsize does not match decoded input");var n=new Buffer(this.pos);this.buffer.copy(n,0,0,this.pos),this.buffer=n}return this.buffer},e._coerced=!0,e};S.Err=g;S.decode=function(r,e,t){for(var n=ne(r),i=we(e),a=new S(n,i);!("eof"in n&&n.eof());)if(a._init_block())a._read_bunzip();else{var s=a.reader.read(32)>>>0;if(s!==a.streamCRC&&T(g.DATA_ERROR,"Bad stream CRC (got "+a.streamCRC.toString(16)+" expected "+s.toString(16)+")"),t&&"eof"in n&&!n.eof())a._start_bunzip(n,i);else break}if("getBuffer"in i)return i.getBuffer()};S.decodeBlock=function(r,e,t){var n=ne(r),i=we(t),a=new S(n,i);a.reader.seek(e);var s=a._get_next_block();if(s&&(a.blockCRC=new ke,a.writeCopies=0,a._read_bunzip()),"getBuffer"in i)return i.getBuffer()};S.table=function(r,e,t){var n=new j;n.delegate=ne(r),n.pos=0,n.readByte=function(){return this.pos++,this.delegate.readByte()},n.delegate.eof&&(n.eof=n.delegate.eof.bind(n.delegate));var i=new j;i.pos=0,i.writeByte=function(){this.pos++};for(var a=new S(n,i),s=a.dbufSize;!("eof"in n&&n.eof());){var o=n.pos*8+a.reader.bitOffset;if(a.reader.hasByte&&(o-=8),a._init_block()){var c=i.pos;a._read_bunzip(),e(o,i.pos-c)}else{var l=a.reader.read(32);if(t&&"eof"in n&&!n.eof())a._start_bunzip(n,i),console.assert(a.dbufSize===s,"shouldn't change block size within multistream file");else break}}};S.Stream=j;S.version=Se.version;S.license=Se.license;Ee.exports=S});import*as Be from"fs";import*as Q from"zlib";var Qe=Pe(),De=512,Ve=65536,We=16777216,$e=67108864,qe=2147483648,Ze={TABLE_OFFSET:0,HASH_A:1,HASH_B:2,TABLE:3};function Ye(){let r=1048577,e=new Uint32Array(256*5);for(let t=0;t<256;t++){let n=t;for(let i=0;i<5;i++){r=(r*125+3)%2796203;let a=(r&65535)<<16;r=(r*125+3)%2796203;let s=r&65535;e[n]=(a|s)>>>0,n+=256}}return e}var Re=Ye(),J=class{file;header;hashTable;blockTable;files;constructor(e,t=!0){if(Buffer.isBuffer(e)?this.file=e:this.file=Be.readFileSync(e),this.header=this.readHeader(),this.hashTable=this.readTable("hash"),this.blockTable=this.readTable("block"),t){let n=this.readFile("(listfile)");n?this.files=n.toString("utf8").trim().split(`\r
|
|
2
|
-
`):this.files=null}else this.files=null}readHeader(){let e=this.file.toString("utf8",0,4),t;if(e==="MPQ")t=this.readMPQHeader(),t.offset=0;else if(e==="MPQ\x1B"){let n=this.readMPQUserDataHeader();t=this.readMPQHeader(n.mpqHeaderOffset),t.offset=n.mpqHeaderOffset,t.userDataHeader=n}else throw new Error("Invalid MPQ file header");return t}readMPQHeader(e=0){let t=this.file.subarray(e,e+32),n={magic:t.toString("utf8",0,4),headerSize:t.readUInt32LE(4),archiveSize:t.readUInt32LE(8),formatVersion:t.readUInt16LE(12),sectorSizeShift:t.readUInt16LE(14),hashTableOffset:t.readUInt32LE(16),blockTableOffset:t.readUInt32LE(20),hashTableEntries:t.readUInt32LE(24),blockTableEntries:t.readUInt32LE(28)};if(n.formatVersion===1){let i=this.file.subarray(e+32,e+32+12);n.extendedBlockTableOffset=i.readUInt32LE(0)+i.readUInt32LE(4)*4294967296,n.hashTableOffsetHigh=i.readInt8(8),n.blockTableOffsetHigh=i.readInt8(10)}return n}readMPQUserDataHeader(){let e=this.file.subarray(0,16),t={magic:e.toString("utf8",0,4),userDataSize:e.readUInt32LE(4),mpqHeaderOffset:e.readUInt32LE(8),userDataHeaderSize:e.readUInt32LE(12)};return t.content=this.file.subarray(16,16+t.userDataHeaderSize),t}readTable(e){let t=e==="hash"?"hashTableOffset":"blockTableOffset",n=e==="hash"?"hashTableEntries":"blockTableEntries",i=this.header[t],a=this.header[n];if(i==null||a==null)throw new Error("Missing "+e+" offset or entries");let
|
|
3
|
-
Searched: `+r.join(", "))}var ie=new Map,ae=null;function Ce(){return ae||(ae=Je()),ae}function ee(r){if(ie.has(r))return ie.get(r);let e=Ce(),t=U.join(e,`protocol${r}.json`);if(!$.existsSync(t))return null;let n=JSON.parse($.readFileSync(t,"utf-8"));return ie.set(r,n),n}function te(){let r=Ce();return $.readdirSync(r).filter(e=>/^protocol\d+\.json$/.test(e)).map(e=>parseInt(e.match(/\d+/)[0],10)).sort((e,t)=>e-t)}var z=class{mpq;header;build=0;protocol;baseProtocol;constructor(e){e&&(this.mpq=new J(e,!1))}init(){let e=ee(29406);if(!e)throw new Error("Base protocol29406 not found. Did postinstall run? Try: npx tsx node_modules/@astefanski/storm-parser/scripts/postinstall.ts");this.baseProtocol=e;let t=this.mpq.header.userDataHeader;if(!t||!t.content)throw new Error("Replay does not have a user data header");let n=new D(t.content,this.baseProtocol.typeinfos);this.header=n.instance(this.baseProtocol.replay_header_typeid),this.build=this.header.m_version.m_baseBuild,this.protocol=this.loadProtocolForBuild(this.build)}loadProtocolForBuild(e){let t=ee(e);if(!t){let n=te(),i=n[0];for(let a of n)a<=e&&a>i&&(i=a);t=ee(i)}if(!t)throw new Error(`No protocol found for build ${e}`);return t}*decodeEventStream(e,t,n,i){if(!this.protocol)throw new Error("Protocol not loaded");let a=0;for(;!e.done();){let s=e.used_bits(),o=e.instance(this.protocol.svaruint32_typeid),c=Object.keys(o)[0],l=o[c];a+=l;let f=i?e.instance(this.protocol.replay_userid_typeid):void 0,u=Number(e.instance(t)),m=n[u];if(!m)throw new Error(`Unknown eventid(${u})`);let b=m[0],d=m[1],h=e.instance(b);h._event=d,h._eventid=u,h._gameloop=a,i&&(h._userid=f),e.byte_align(),h._bits=e.used_bits()-s,yield h}}getDetails(){if(!this.protocol)throw new Error("Protocol not loaded");let e=this.mpq.readFile("replay.details");return e?new D(e,this.protocol.typeinfos).instance(this.protocol.game_details_typeid):null}getInitData(){if(!this.protocol)throw new Error("Protocol not loaded");let e=this.mpq.readFile("replay.initData");return e?new O(e,this.protocol.typeinfos).instance(this.protocol.replay_initdata_typeid):null}getTrackerEvents(){if(!this.protocol)throw new Error("Protocol not loaded");let e=this.mpq.readFile("replay.tracker.events");if(!e)return[];let t=new D(e,this.protocol.typeinfos);return Array.from(this.decodeEventStream(t,this.protocol.tracker_eventid_typeid,this.protocol.tracker_event_types,!1))}getGameEvents(){if(!this.protocol)throw new Error("Protocol not loaded");let e=this.mpq.readFile("replay.game.events");if(!e)return[];let t=new O(e,this.protocol.typeinfos);return Array.from(this.decodeEventStream(t,this.protocol.game_eventid_typeid,this.protocol.game_event_types,!0))}getAttributeEvents(){if(!this.protocol)throw new Error("Protocol not loaded");let e=this.mpq.readFile("replay.attributes.events");return e?new D(e,this.protocol.typeinfos).instance(this.protocol.replay_attributes_events_typeid):null}extractFile(e){return this.mpq.readFile(e)}getHeader(){return this.header}getBuild(){return this.build}};var se=class extends z{constructor(e){super();let t=e;if(!t){let n=te();t=n[n.length-1]}this.protocol=this.loadProtocolForBuild(t)}parseTracker(e){if(!this.protocol)return[];try{let t=new D(e,this.protocol.typeinfos);return Array.from(this.decodeEventStream(t,this.protocol.tracker_eventid_typeid,this.protocol.tracker_event_types,!1))}catch(t){return console.error("[LiveStreamParser] Failed to parse tracker events",t),[]}}parseGame(e){if(!this.protocol)return[];try{let t=new O(e,this.protocol.typeinfos);return Array.from(this.decodeEventStream(t,this.protocol.game_eventid_typeid,this.protocol.game_event_types,!0))}catch(t){return console.error("[LiveStreamParser] Failed to parse game events",t),[]}}};var Ie=["Abathur","Alarak","Alexstrasza","Ana","Anduin","Anubarak","Artanis","Arthas","Auriel","Azmodan","Blaze","Brightwing","Cassia","Chen","Cho","Chromie","Deathwing","Deckard","Dehaka","Diablo","DVa","ETC","Falstad","Fenix","Gall","Garrosh","Gazlowe","Genji","Greymane","Guldan","Hanzo","Hogger","Illidan","Imperius","Jaina","Johanna","Junkrat","Kaelthas","KelThuzad","Kerrigan","Kharazim","Leoric","LiLi","LiMing","LtMorales","Lunara","Maiev","Malfurion","MalGanis","Malthael","Medivh","Mei","Mephisto","Muradin","Murky","Nazeebo","Nova","Orphea","Probius","Qhira","Ragnaros","Raynor","Rehgar","Rexxar","Samuro","SgtHammer","Sonya","Stitches","Stukov","Sylvanas","Tassadar","TheButcher","TheLostVikings","Thrall","Tracer","Tychus","Tyrael","Tyrande","Uther","Valeera","Valla","Varian","Whitemane","Xul","Yrel","Zagara","Zarya","Zeratul","Zuljin"],Ae={FaerieDragon:"Brightwing",Amazon:"Cassia",Barbarian:"Sonya",Crusader:"Johanna",DemonHunter:"Valla",WitchDoctor:"Nazeebo",Monk:"Kharazim",Wizard:"LiMing",Tinker:"Gazlowe",Medic:"LtMorales",L90ETC:"ETC",Butcher:"TheButcher",LostVikings:"TheLostVikings",Necromancer:"Xul",Dryad:"Lunara",Shapeshifter:"Greymane",ChoGall:"Cho"};function q(r){if(!r)return null;if(Ie.includes(r))return r;if(Ae[r])return Ae[r];let e=r.replace(/[^a-zA-Z0-9]/g,"").toLowerCase(),t=Ie.find(n=>n.toLowerCase()===e);return t||null}var Me={TownCannonTowerL2:"Fort Tower",TownCannonTowerL3:"Keep Tower",TownTownHallL2:"Fort",TownTownHallL3:"Keep",TownMoonwellL2:"Fort Well",TownMoonwellL3:"Keep Well"},et={MercLanerMeleeKnight:"Bruiser Camp",MercLanerRangedMage:"Bruiser Camp",MercLanerSiegeGiant:"Siege Camp",MercLanerRangedMinion:"Siege Camp"};function B(r){return Buffer.isBuffer(r)?r.toString("utf8"):typeof r=="string"?r:String(r??"")}function v(r,e){if(!r)return;let t=r.find(n=>B(n.m_key)===e);return t!==void 0?t.m_value:void 0}function re(r,e){if(!r)return;let t=r.find(n=>B(n.m_key)===e);return t!==void 0?B(t.m_value):void 0}function w(r,e){if(!r)return;let t=r.find(n=>B(n.m_key)===e);return t!==void 0?t.m_value:void 0}function oe(r,e){return`${r}-${e}`}function R(r,e){return(r-e)/16}function He(r,e,t){let n={playerIDMap:{},loopGameStart:0,loopGameEnd:0,unitIndex:{},heroUnits:{},heroLives:{}};t.bans||(t.bans={0:[],1:[]}),t.levelTimes={0:{},1:{}},t.takedowns=[],t.structures={},t.XPBreakdown=[],t.mercs={captures:[],units:{}},t.objective={0:{count:0,events:[]},1:{count:0,events:[]},type:t.map||""};for(let i of r)switch(n.loopGameEnd=Math.max(n.loopGameEnd,i._gameloop),i._event){case"NNet.Replay.Tracker.SStatGameEvent":tt(i,n,e,t);break;case"NNet.Replay.Tracker.SHeroBannedEvent":if(i.m_hero){let a=B(i.m_hero),s=q(a);if(!s)break;let o=i.m_controllingTeam===2?1:0;if(t.bans&&t.bans[o]){let c=t.bans[o].length+1,l=t.bans[0].length+t.bans[1].length+1;t.bans[o].push({hero:s,order:c,absolute:l})}}break;case"NNet.Replay.Tracker.SUnitBornEvent":it(i,n,t);break;case"NNet.Replay.Tracker.SUnitDiedEvent":at(i,n,t);break;case"NNet.Replay.Tracker.SUnitOwnerChangeEvent":st(i,n);break}return t.loopGameStart=n.loopGameStart,t.loopLength=n.loopGameEnd,t.length=(n.loopGameEnd-n.loopGameStart)/16,ot(n,e),{playerIDMap:n.playerIDMap}}function tt(r,e,t,n){let i=B(r.m_eventName),a=r.m_intData,s=r.m_stringData,o=r.m_fixedData;switch(i){case"PlayerInit":{let c=v(a,"PlayerID"),l=re(s,"ToonHandle");c!==void 0&&l&&t[l]&&(e.playerIDMap[c]=l);break}case"GatesOpen":e.loopGameStart=r._gameloop;break;case"LevelUp":{let c=v(a,"PlayerID"),l=v(a,"Level");if(c===void 0||l===void 0)break;let f;if(c>=1&&c<=5)f="0";else if(c>=6&&c<=10)f="1";else break;n.levelTimes[f][String(l)]||(n.levelTimes[f][String(l)]={loop:r._gameloop,level:l,team:f,time:R(r._gameloop,e.loopGameStart)});break}case"TalentChosen":{let c=v(a,"PlayerID"),l=re(s,"PurchaseName");if(c===void 0||!l||l==="Win"||l==="Loss"||l.startsWith("Hero"))break;let f=n.map?.replace(/\s+/g,"")||"";if(l===f)break;let u=e.playerIDMap[c];if(!u||!t[u])break;let m=["Tier1Choice","Tier2Choice","Tier3Choice","Tier4Choice","Tier5Choice","Tier6Choice","Tier7Choice"];for(let b of m)if(!t[u].talents[b]){t[u].talents[b]=l;break}break}case"PlayerDeath":{let c=v(a,"PlayerID"),l=v(a,"KillingPlayer"),f=w(o,"PositionX")??0,u=w(o,"PositionY")??0;if(c===void 0)break;let m=e.playerIDMap[c];if(!m)break;let b={player:m,hero:t[m]?.hero||""},d=[],h=t[m]?.team;if(l&&l>0){let _=e.playerIDMap[l];_&&t[_]&&d.push({player:_,hero:t[_].hero})}for(let[_,y]of Object.entries(e.playerIDMap)){let x=t[y];!x||x.team===h||parseInt(_)===l||d.push({player:y,hero:x.hero})}let p={loop:r._gameloop,time:R(r._gameloop,e.loopGameStart),x:f,y:u,killers:d,victim:b};n.takedowns.push(p),t[m]&&t[m].deaths.push(p);for(let _ of d)t[_.player]&&t[_.player].takedowns.push(p);break}case"PeriodicXPBreakdown":{let c=v(a,"Team");if(c===void 0)break;let l={GameTime:v(a,"GameTime")??0,PreviousGameTime:v(a,"PreviousGameTime")??0,MinionXP:w(o,"MinionXP")??0,CreepXP:w(o,"CreepXP")??0,StructureXP:w(o,"StructureXP")??0,HeroXP:w(o,"HeroXP")??0,TrickleXP:w(o,"TrickleXP")??0};n.XPBreakdown.push({loop:r._gameloop,time:R(r._gameloop,e.loopGameStart),team:c,teamLevel:v(a,"TeamLevel")??0,breakdown:l,theoreticalMinionXP:v(a,"TheoreticalMinionXP")??0});break}case"EndOfGameXPBreakdown":{let c=v(a,"Team");if(c===void 0)break;n.XPBreakdown.push({loop:r._gameloop,time:R(r._gameloop,e.loopGameStart),team:c,theoreticalMinionXP:v(a,"TheoreticalMinionXP")??0,breakdown:{GameTime:0,PreviousGameTime:0,MinionXP:w(o,"MinionXP")??0,CreepXP:w(o,"CreepXP")??0,StructureXP:w(o,"StructureXP")??0,HeroXP:w(o,"HeroXP")??0,TrickleXP:w(o,"TrickleXP")??0}});break}case"JungleCampCapture":{let c=v(a,"CampTeam")??v(a,"Team")??0;n.mercs.captures.push({loop:r._gameloop,type:re(s,"CampType")??re(s,"Result")??"Unknown Camp",team:c,time:R(r._gameloop,e.loopGameStart)});break}case"EndOfGameTalentChoices":{let c=v(a,"PlayerID");if(c===void 0)break;let l=e.playerIDMap[c];if(!l||!t[l])break;let f={};if(s)for(let u of s){let m=B(u.m_key),b=B(u.m_value);m==="Tier 1 Choice"&&b?f.Tier1Choice=b:m==="Tier 2 Choice"&&b?f.Tier2Choice=b:m==="Tier 3 Choice"&&b?f.Tier3Choice=b:m==="Tier 4 Choice"&&b?f.Tier4Choice=b:m==="Tier 5 Choice"&&b?f.Tier5Choice=b:m==="Tier 6 Choice"&&b?f.Tier6Choice=b:m==="Tier 7 Choice"&&b&&(f.Tier7Choice=b)}t[l].talents=f;break}default:nt(i,r,e,n,a,o);break}}var rt=new Set(["SoulEatersSpawned","TributeCollected","RavenCurseActivated","AltarCaptured","SkyTempleShotsFired","DragonKnightActivated","GardenTerrorActivated","InfernalShrineCaptured","PunisherKilled","VolskayaVehicleCapture","BraxisWaveStart","ImmortalDefeated","NukeExploded","PayloadDelivered","AlteracCavalryCharge","AlteracCavalry"]);function nt(r,e,t,n,i,a){if(!rt.has(r)||!i)return;let s=v(i,"Team")??v(i,"Event")??0,o=s===0||s===1?s:0,c={team:s,loop:e._gameloop,time:R(e._gameloop,t.loopGameStart),score:v(i,"Score"),duration:w(a,"Duration")};n.objective[o].events.push(c),n.objective[o].count=n.objective[o].events.length}function it(r,e,t){let n=B(r.m_unitTypeName),i=r.m_unitTagIndex,a=r.m_unitTagRecycle,s=oe(i,a),o=r.m_controlPlayerId??r.m_upkeepPlayerId,c=r.m_x??0,l=r.m_y??0,f;if(o>=1&&o<=5?f=0:o>=6&&o<=10?f=1:o===11?f=0:o===12?f=1:f=o<=5?0:1,e.unitIndex[s]={type:n,playerId:o,team:f,x:c,y:l,bornLoop:r._gameloop},n.startsWith("Town")&&Me[n]&&(t.structures[s]={type:n,name:Me[n],tag:i,rtag:a,x:c,y:l,team:f}),n.startsWith("Hero")&&o>=1&&o<=10){e.heroUnits[s]=o,e.heroLives[o]||(e.heroLives[o]=[]);let u=R(r._gameloop,e.loopGameStart);e.heroLives[o].push({born:u,locations:[{x:c,y:l,time:u}],duration:0})}if(et[n]){let m=t.mercs.captures[t.mercs.captures.length-1]?.loop??r._gameloop;t.mercs.units[s]={loop:m,team:f,type:n,locations:[{x:c,y:l}],time:R(m,e.loopGameStart),duration:0}}}function at(r,e,t){let n=oe(r.m_unitTagIndex,r.m_unitTagRecycle),i=R(r._gameloop,e.loopGameStart);t.structures[n]&&(t.structures[n].destroyedLoop=r._gameloop,t.structures[n].destroyed=i),t.mercs.units[n]&&(t.mercs.units[n].duration=i-t.mercs.units[n].time);let a=e.heroUnits[n];if(a!==void 0&&e.heroLives[a]){let s=e.heroLives[a],o=s[s.length-1];o&&o.died===void 0&&(o.died=i,o.duration=i-o.born)}}function st(r,e){let t=oe(r.m_unitTagIndex,r.m_unitTagRecycle),n=r.m_controlPlayerId??r.m_upkeepPlayerId;e.unitIndex[t]&&(e.unitIndex[t].playerId=n,n>=1&&n<=5?e.unitIndex[t].team=0:n>=6&&n<=10&&(e.unitIndex[t].team=1))}function ot(r,e){for(let[t,n]of Object.entries(r.heroLives)){let i=parseInt(t,10),a=r.playerIDMap[i];if(!a||!e[a])continue;for(let o of n)if(o.died===void 0){let c=o.locations[o.locations.length-1];o.duration=c?c.time-o.born:0}let s="";for(let[o,c]of Object.entries(r.heroUnits))if(c===i){s=o;break}s&&(e[a].units[s]={lives:n})}}var ct=["DamageTaken","CreepDamage","Healing","HeroDamage","MinionDamage","SelfHealing","SiegeDamage","ProtectionGivenToAllies","TeamfightDamageTaken","TeamfightHealingDone","TeamfightHeroDamage","TimeCCdEnemyHeroes","TimeRootingEnemyHeroes","TimeSpentDead","TimeStunningEnemyHeroes","TimeSilencingEnemyHeroes"];function lt(){return{DamageTaken:0,CreepDamage:0,Healing:0,HeroDamage:0,MinionDamage:0,SelfHealing:0,SiegeDamage:0,ProtectionGivenToAllies:0,TeamfightDamageTaken:0,TeamfightHealingDone:0,TeamfightHeroDamage:0,TimeCCdEnemyHeroes:0,TimeRootingEnemyHeroes:0,TimeSpentDead:0,TimeStunningEnemyHeroes:0,TimeSilencingEnemyHeroes:0,avgTimeSpentDead:0,timeDeadPct:0}}function ft(){return{mercCaptures:0,mercUptime:0,mercUptimePercent:0,structures:{},KDA:0,PPK:0,timeTo10:0,totals:lt(),levelAdvTime:0,maxLevelAdv:0,avgLevelAdv:0,levelAdvPct:0,uptime:[],uptimeHistogram:{},wipes:0,avgHeroesAlive:0,aces:0,timeWithHeroAdv:0,pctWithHeroAdv:0,passiveXPRate:0,passiveXPDiff:0,passiveXPGain:0}}function Oe(r,e){pt(r),dt(r,e),mt(r,e),bt(r),ht(r,e),gt(r)}function dt(r,e){for(let t of["0","1"]){let n=r.teams[t];if(!n)continue;n.names=[],n.heroes=[],n.tags=[],n.stats=ft();for(let u of n.ids){let m=e[u];m&&(n.names.push(m.name),n.heroes.push(m.hero),n.tags.push(m.tag))}for(let u of n.ids){let m=e[u];if(m)for(let b of ct){let d=m.gameStats[b];typeof d=="number"&&(n.stats.totals[b]+=d)}}let i=n.ids.reduce((u,m)=>u+(e[m]?.gameStats.Deaths??0),0);i>0&&(n.stats.totals.avgTimeSpentDead=n.stats.totals.TimeSpentDead/i),r.length>0&&(n.stats.totals.timeDeadPct=n.stats.totals.TimeSpentDead/(r.length*n.ids.length));let a=n.takedowns,s=i;n.stats.KDA=s>0?a/s:a,n.stats.PPK=a>0?r.takedowns.filter(u=>n.ids.includes(u.killers[0]?.player)).reduce((u,m)=>u+m.killers.length,0)/a:0;let o=r.levelTimes[t];o?.["10"]&&(n.stats.timeTo10=o[10].time);let c=parseInt(t,10),l=r.mercs.captures.filter(u=>u.team===c);n.stats.mercCaptures=l.length;let f=0;for(let u of Object.values(r.mercs.units))u.team===c&&u.duration>0&&(f+=u.duration);n.stats.mercUptime=f,n.stats.mercUptimePercent=r.length>0?f/r.length:0,ut(r,n,t)}}function ut(r,e,t){let n=parseInt(t,10),i=n===0?1:0,a={};for(let s of Object.values(r.structures)){let o=s.name;a[o]||(a[o]={lost:0,destroyed:0,first:r.length}),s.team===i&&s.destroyed!==void 0&&(a[o].destroyed++,a[o].first=Math.min(a[o].first,s.destroyed)),s.team===n&&s.destroyed!==void 0&&a[o].lost++}e.stats.structures=a}function mt(r,e){let t=r.length/60;for(let n of Object.values(e)){let i=n.gameStats,a=i.Deaths??0,s=i.TeamTakedowns??0;t>0&&(i.DPM=(i.HeroDamage??0)/t,i.HPM=((i.Healing??0)+(i.SelfHealing??0))/t,i.XPM=(i.ExperienceContribution??0)/t),i.KDA=a>0?(i.Takedowns??0)/a:i.Takedowns??0,i.KillParticipation=s>0?(i.Takedowns??0)/s:0,i.damageDonePerDeath=a>0?(i.HeroDamage??0)/a:i.HeroDamage??0,i.damageTakenPerDeath=a>0?(i.DamageTaken??0)/a:i.DamageTaken??0,i.healingDonePerDeath=a>0?((i.Healing??0)+(i.SelfHealing??0))/a:(i.Healing??0)+(i.SelfHealing??0),i.length=r.length}}function pt(r){let e=0,t=0,n=new Set(r.teams[0]?.ids||[]);for(let i of r.takedowns)n.has(i.victim.player)?t++:e++;r.team0Takedowns=e,r.team1Takedowns=t,r.teams[0]&&(r.teams[0].takedowns=e),r.teams[1]&&(r.teams[1].takedowns=t)}function bt(r){let e=r.levelTimes[0]||{},t=r.levelTimes[1]||{},n=[];for(let l of Object.values(e))n.push({time:l.time,team:0,level:l.level});for(let l of Object.values(t))n.push({time:l.time,team:1,level:l.level});if(n.sort((l,f)=>l.time-f.time),n.length===0){r.levelAdvTimeline=[];return}let i=[],a=0,s=0,o=n[0].time;for(let l of n){let f=a-s;l.time>o&&i.push({start:o,end:l.time,levelDiff:f,length:l.time-o}),l.team===0?a=l.level:s=l.level,o=l.time}let c=a-s;r.length>o&&i.push({start:o,end:r.length,levelDiff:c,length:r.length-o}),r.levelAdvTimeline=i;for(let l of["0","1"]){let f=r.teams[l];if(!f)continue;let u=l==="0"?1:-1,m=0,b=0,d=0,h=0;for(let p of i){let _=p.levelDiff*u;_>0&&(m+=p.length),b=Math.max(b,_),d+=_*p.length,h+=p.length}f.stats.levelAdvTime=m,f.stats.maxLevelAdv=b,f.stats.avgLevelAdv=h>0?d/h:0,f.stats.levelAdvPct=r.length>0?m/r.length:0}}function ht(r,e){for(let a of["0","1"]){let s=r.teams[a];if(!s)continue;let o=[];for(let p of s.ids){let _=e[p];if(_)for(let y of _.deaths){o.push({time:y.time,delta:-1});let x=y.time+_t(_.gameStats.Level??1);x<r.length&&o.push({time:x,delta:1})}}o.sort((p,_)=>p.time-_.time);let c=[{time:0,heroes:s.ids.length}],l=s.ids.length;for(let p of o)l+=p.delta,l=Math.max(0,Math.min(s.ids.length,l)),c.push({time:p.time,heroes:l});s.stats.uptime=c;let f={};for(let p=0;p<c.length;p++){let y=(p<c.length-1?c[p+1].time:r.length)-c[p].time,x=String(c[p].heroes);f[x]=(f[x]||0)+y}s.stats.uptimeHistogram=f;let u=0,m=0;for(let p=0;p<c.length;p++){let y=(p<c.length-1?c[p+1].time:r.length)-c[p].time;u+=c[p].heroes*y,m+=y}s.stats.avgHeroesAlive=m>0?u/m:s.ids.length,s.stats.wipes=c.filter(p=>p.heroes===0).length,s.stats.aces=0;let b=a==="0"?"1":"0",d=r.teams[b];d?.stats?.uptime&&(s.stats.aces=d.stats.uptime.filter(p=>p.heroes===0).length);let h=r.XPBreakdown.filter(p=>p.team===parseInt(a,10));if(h.length>0){let _=h[h.length-1].breakdown.TrickleXP;s.stats.passiveXPGain=_,s.stats.passiveXPRate=r.length>0?_/(r.length/60):0}}for(let a of["0","1"]){let s=r.teams[a],o=a==="0"?"1":"0",c=r.teams[o];if(!s||!c)continue;let l=s.stats.uptime,f=c.stats.uptime;if(!l.length||!f.length)continue;let u=new Set;for(let d of l)u.add(d.time);for(let d of f)u.add(d.time);let m=Array.from(u).sort((d,h)=>d-h),b=0;for(let d=0;d<m.length;d++){let h=m[d],_=(d<m.length-1?m[d+1]:r.length)-h,y=Le(l,h),x=Le(f,h);y>x&&(b+=_)}s.stats.timeWithHeroAdv=b,s.stats.pctWithHeroAdv=r.length>0?b/r.length:0}let t=r.teams[0]?.stats.passiveXPRate??0,n=r.teams[1]?.stats.passiveXPRate??0,i=(t+n)/2;r.teams[0]&&(r.teams[0].stats.passiveXPDiff=i>0?t/i:0),r.teams[1]&&(r.teams[1].stats.passiveXPDiff=i>0?n/i:0)}function Le(r,e){let t=0;for(let n of r)if(n.time<=e)t=n.heroes;else break;return t}function _t(r){return r<=1?15:r<=5?15+(r-1)*2:r<=10?23+(r-5)*3:r<=15?38+(r-10)*4:58+(r-15)*5}function gt(r){let e=1/0,t=-1,n=1/0,i=-1;for(let s of Object.values(r.structures))s.destroyed!==void 0&&(s.name==="Fort"&&s.destroyed<e&&(e=s.destroyed,t=s.team===0?1:0),s.name==="Keep"&&s.destroyed<n&&(n=s.destroyed,i=s.team===0?1:0));t>=0&&(r.firstFort=t,r.firstFortWin=t===r.winner),i>=0&&(r.firstKeep=i,r.firstKeepWin=i===r.winner);let a=[...r.objective[0].events.map(s=>({...s,assignedTeam:0})),...r.objective[1].events.map(s=>({...s,assignedTeam:1}))].sort((s,o)=>s.loop-o.loop);a.length>0&&(r.firstObjective=a[0].assignedTeam,r.firstObjectiveWin=a[0].assignedTeam===r.winner),r.firstPickWin=r.picks.first===r.winner}function k(r){return Buffer.isBuffer(r)?r.toString("utf8"):typeof r=="string"?r:String(r??"")}var ce=class{static async analyze(e){try{let t=new z(e);await t.init();let n=t.getDetails();if(!n)throw new Error("Missing replay.details from parsed MPQ archive");let i=t.getTrackerEvents(),a=t.getInitData(),o=t.getHeader()?.m_version??{},c={m_flags:o.m_flags??0,m_major:o.m_major??0,m_minor:o.m_minor??0,m_revision:o.m_revision??0,m_build:o.m_baseBuild??t.getBuild(),m_baseBuild:o.m_baseBuild??t.getBuild()},l=n.m_playerList.find(b=>b?.m_toon)?.m_toon,f={version:c,map:k(n.m_title),isBlizzardMap:n.m_isBlizzardMap,timeLocalOffset:Number(n.m_timeLocalOffset),gameSpeed:n.m_gameSpeed,date:this.fileTimeToDate(n.m_timeUTC).toISOString(),rawDate:Number(n.m_timeUTC),length:0,winner:-1,region:l?.m_region,playerIDs:[],heroes:[],levelTimes:{0:{},1:{}},bans:{0:[],1:[]},picks:{0:[],1:[],first:0},XPBreakdown:[],takedowns:[],mercs:{captures:[],units:{}},team0Takedowns:0,team1Takedowns:0,structures:{},objective:{0:{count:0,events:[]},1:{count:0,events:[]},type:""},teams:{0:this.emptyTeam(),1:this.emptyTeam()},winningPlayers:[],levelAdvTimeline:[],firstPickWin:!1};f.objective.type=f.map||"";let u={};for(let b of n.m_playerList){if(!b?.m_toon)continue;let d=b.m_toon,h=k(d.m_programId),p=`${d.m_region}-${h}-${d.m_realm}-${d.m_id}`,_=k(b.m_hero),y=q(_)||_;u[p]={hero:y,name:k(b.m_name),uuid:d.m_id,region:d.m_region,realm:d.m_realm,ToonHandle:p,tag:0,team:b.m_teamId,win:b.m_result===1,skin:"",mount:"",banner:"",spray:"",clanTag:"",highestLeague:0,combinedRaceLevels:0,randomSeed:0,announcer:"",silenced:!1,voiceSilenced:!1,gameStats:{},awards:[],talents:{},takedowns:[],deaths:[],units:{}},f.playerIDs.push(p),f.heroes.push(y)}this.extractBattleTags(t,n,u),this.extractDraft(a,f,n),this.extractCosmetics(a,n,u);let{playerIDMap:m}=He(i,u,f);this.processScoreEvents(i,m,u);for(let[b,d]of Object.entries(u)){d.win&&(f.winner=d.team,f.winningPlayers.push(b));let h=f.teams[d.team.toString()];h&&(h.level=Math.max(h.level,d.gameStats.Level||0),h.ids.push(b))}return Oe(f,u),{status:1,match:f,players:u}}catch(t){return console.error("ReplayAnalyzer Error:",t),{status:-2,error:String(t)}}}static emptyTeam(){return{level:0,takedowns:0,ids:[],names:[],heroes:[],tags:[],stats:{mercCaptures:0,mercUptime:0,mercUptimePercent:0,structures:{},KDA:0,PPK:0,timeTo10:0,totals:{DamageTaken:0,CreepDamage:0,Healing:0,HeroDamage:0,MinionDamage:0,SelfHealing:0,SiegeDamage:0,ProtectionGivenToAllies:0,TeamfightDamageTaken:0,TeamfightHealingDone:0,TeamfightHeroDamage:0,TimeCCdEnemyHeroes:0,TimeRootingEnemyHeroes:0,TimeSpentDead:0,TimeStunningEnemyHeroes:0,TimeSilencingEnemyHeroes:0,avgTimeSpentDead:0,timeDeadPct:0},levelAdvTime:0,maxLevelAdv:0,avgLevelAdv:0,levelAdvPct:0,uptime:[],uptimeHistogram:{},wipes:0,avgHeroesAlive:0,aces:0,timeWithHeroAdv:0,pctWithHeroAdv:0,passiveXPRate:0,passiveXPDiff:0,passiveXPGain:0}}}static extractBattleTags(e,t,n){let i=e.extractFile("replay.server.battlelobby");if(i)try{let a=new RegExp("([\\p{L}\\d]{3,24}#\\d{4,10})[z\xD8]?","gu"),s=i.toString("utf8").match(a);if(!s)return;let o=0;for(let c of t.m_playerList){if(!c?.m_toon)continue;let l=k(c.m_name);for(;o<s.length;){let u=s[o].split("#"),m=u[0],b=u[1].replace(/[zØ]/g,"");if(o++,m===l){let d=c.m_toon,h=`${d.m_region}-${k(d.m_programId)}-${d.m_realm}-${d.m_id}`;n[h]&&(n[h].tag=parseInt(b,10)||0);break}}}}catch(a){console.error("BattleTag regex error:",a)}}static extractDraft(e,t,n){if(e)try{let i=e.m_syncLobbyState;if(!i)return;let a=i.m_lobbyState,s=i.m_gameDescription;if(!a)return;s&&(t.randomValue=s.m_randomValue,t.gameOptions=s.m_gameOptions);let o=[],c=[];for(let d of n.m_playerList){if(!d?.m_toon)continue;let h=k(d.m_hero),p=q(h)||h;d.m_teamId===0?o.push(p):d.m_teamId===1&&c.push(p)}t.picks={0:o,1:c,first:0};let l,f=s?.m_gameOptions;if(f&&typeof f.m_ammId=="number"){let d=f.m_ammId;d===50001?l="Quick Match":d===50031?l="ARAM":d===50041?l="Unranked Draft":d===50051?l="Custom":d===50061?l="Hero League":d===50071?l="Team League":d===50091&&(l="Storm League")}if(!l&&typeof a.m_gameMode=="number"){let d=a.m_gameMode;d===3?l="Quick Match":d===4?l="Custom":d===5?l="Hero League":d===6?l="Team League":d===7?l="Unranked Draft":d===8&&(l="ARAM")}if(t.mode=l,typeof a.m_gameType=="number"&&(t.type=a.m_gameType),!a.m_slots)return;let m=a.m_pickedMapTag,b=0;m!==void 0&&(b=a.m_firstPickTeam??0,t.picks.first=b)}catch{}}static extractCosmetics(e,t,n){if(e)try{let i=e.m_syncLobbyState;if(!i)return;let a=i.m_lobbyState;if(!a)return;let s=a.m_slots,o=i.m_userInitialData;if(!s)return;let c=0;for(let l of t.m_playerList){if(!l?.m_toon)continue;let f=l.m_toon,u=`${f.m_region}-${k(f.m_programId)}-${f.m_realm}-${f.m_id}`,m=n[u];for(;c<s.length;){let b=s[c];c++;let d=b.m_hero;if(!(!d||Buffer.isBuffer(d)&&d.length===0)){if(m&&(m.skin=k(b.m_skin)||"",m.mount=k(b.m_mount)||"",m.announcer=k(b.m_announcerPack)||"",m.banner=k(b.m_banner)||"",m.spray=k(b.m_spray)||"",m.silenced=!!b.m_hasSilencePenalty,m.voiceSilenced=!!b.m_hasVoiceSilencePenalty,o)){let h=o.find(p=>k(p.m_name)===m.name);h&&(m.clanTag=k(h.m_clanTag),m.highestLeague=h.m_highestLeague,m.combinedRaceLevels=h.m_combinedRaceLevels,m.randomSeed=h.m_randomSeed)}break}}}}catch{}}static processScoreEvents(e,t,n){for(let i of e){if(i._event!=="NNet.Replay.Tracker.SScoreResultEvent")continue;let a=i.m_instanceList;for(let s of a){let o=k(s.m_name),c=s.m_values,l=o.startsWith("EndOfMatchAward"),f=0;for(let u of c)if(u&&u.length>0&&u[0]!==void 0){let m=f+1,b=t[m];if(b&&n[b]){let d=typeof u[0]=="object"&&u[0]!==null&&"m_value"in u[0]?u[0].m_value:u[0];d!=null&&(l?d===1&&n[b].awards.push(o):n[b].gameStats[o]=d)}f++}else u&&u.length===0&&f++}}}static fileTimeToDate(e){return new Date(Number(e)/1e4-116444736e5)}};export{se as LiveStreamParser,ce as ReplayAnalyzer,z as ReplayParser};
|
|
1
|
+
var G=(r,e)=>()=>(e||r((e={exports:{}}).exports,e),e.exports);var pe=G((xt,me)=>{"use strict";var ue=[0,1,3,7,15,31,63,127,255],K=function(r){this.stream=r,this.bitOffset=0,this.curByte=0,this.hasByte=!1};K.prototype._ensureByte=function(){this.hasByte||(this.curByte=this.stream.readByte(),this.hasByte=!0)};K.prototype.read=function(r){for(var e=0;r>0;){this._ensureByte();var t=8-this.bitOffset;if(r>=t)e<<=t,e|=ue[t]&this.curByte,this.hasByte=!1,this.bitOffset=0,r-=t;else{e<<=r;var n=t-r;e|=(this.curByte&ue[r]<<n)>>n,this.bitOffset+=r,r=0}}return e};K.prototype.seek=function(r){var e=r%8,t=(r-e)/8;this.bitOffset=e,this.stream.seek(t),this.hasByte=!1};K.prototype.pi=function(){var r=new Buffer(6),e;for(e=0;e<r.length;e++)r[e]=this.read(8);return r.toString("hex")};me.exports=K});var he=G((vt,be)=>{"use strict";var H=function(){};H.prototype.readByte=function(){throw new Error("abstract method readByte() not implemented")};H.prototype.read=function(r,e,t){for(var n=0;n<t;){var i=this.readByte();if(i<0)return n===0?-1:n;r[e++]=i,n++}return n};H.prototype.seek=function(r){throw new Error("abstract method seek() not implemented")};H.prototype.writeByte=function(r){throw new Error("abstract method readByte() not implemented")};H.prototype.write=function(r,e,t){var n;for(n=0;n<t;n++)this.writeByte(r[e++]);return t};H.prototype.flush=function(){};be.exports=H});var ge=G((Tt,_e)=>{"use strict";_e.exports=(function(){var r=new Uint32Array([0,79764919,159529838,222504665,319059676,398814059,445009330,507990021,638119352,583659535,797628118,726387553,890018660,835552979,1015980042,944750013,1276238704,1221641927,1167319070,1095957929,1595256236,1540665371,1452775106,1381403509,1780037320,1859660671,1671105958,1733955601,2031960084,2111593891,1889500026,1952343757,2552477408,2632100695,2443283854,2506133561,2334638140,2414271883,2191915858,2254759653,3190512472,3135915759,3081330742,3009969537,2905550212,2850959411,2762807018,2691435357,3560074640,3505614887,3719321342,3648080713,3342211916,3287746299,3467911202,3396681109,4063920168,4143685023,4223187782,4286162673,3779000052,3858754371,3904687514,3967668269,881225847,809987520,1023691545,969234094,662832811,591600412,771767749,717299826,311336399,374308984,453813921,533576470,25881363,88864420,134795389,214552010,2023205639,2086057648,1897238633,1976864222,1804852699,1867694188,1645340341,1724971778,1587496639,1516133128,1461550545,1406951526,1302016099,1230646740,1142491917,1087903418,2896545431,2825181984,2770861561,2716262478,3215044683,3143675388,3055782693,3001194130,2326604591,2389456536,2200899649,2280525302,2578013683,2640855108,2418763421,2498394922,3769900519,3832873040,3912640137,3992402750,4088425275,4151408268,4197601365,4277358050,3334271071,3263032808,3476998961,3422541446,3585640067,3514407732,3694837229,3640369242,1762451694,1842216281,1619975040,1682949687,2047383090,2127137669,1938468188,2001449195,1325665622,1271206113,1183200824,1111960463,1543535498,1489069629,1434599652,1363369299,622672798,568075817,748617968,677256519,907627842,853037301,1067152940,995781531,51762726,131386257,177728840,240578815,269590778,349224269,429104020,491947555,4046411278,4126034873,4172115296,4234965207,3794477266,3874110821,3953728444,4016571915,3609705398,3555108353,3735388376,3664026991,3290680682,3236090077,3449943556,3378572211,3174993278,3120533705,3032266256,2961025959,2923101090,2868635157,2813903052,2742672763,2604032198,2683796849,2461293480,2524268063,2284983834,2364738477,2175806836,2238787779,1569362073,1498123566,1409854455,1355396672,1317987909,1246755826,1192025387,1137557660,2072149281,2135122070,1912620623,1992383480,1753615357,1816598090,1627664531,1707420964,295390185,358241886,404320391,483945776,43990325,106832002,186451547,266083308,932423249,861060070,1041341759,986742920,613929101,542559546,756411363,701822548,3316196985,3244833742,3425377559,3370778784,3601682597,3530312978,3744426955,3689838204,3819031489,3881883254,3928223919,4007849240,4037393693,4100235434,4180117107,4259748804,2310601993,2373574846,2151335527,2231098320,2596047829,2659030626,2470359227,2550115596,2947551409,2876312838,2788305887,2733848168,3165939309,3094707162,3040238851,2985771188]),e=function(){var t=4294967295;this.getCRC=function(){return~t>>>0},this.updateCRC=function(n){t=t<<8^r[(t>>>24^n)&255]},this.updateCRCRun=function(n,i){for(;i-- >0;)t=t<<8^r[(t>>>24^n)&255]}};return e})()});var ye=G((kt,Ue)=>{Ue.exports={name:"seek-bzip",version:"2.0.0",contributors:["C. Scott Ananian (http://cscott.net)","Eli Skeggs","Kevin Kwok","Rob Landley (http://landley.net)"],description:"a pure-JavaScript Node.JS module for random-access decoding bzip2 data",main:"./lib/index.js",repository:{type:"git",url:"https://github.com/cscott/seek-bzip.git"},license:"MIT",bin:{"seek-bunzip":"./bin/seek-bunzip","seek-table":"./bin/seek-bzip-table"},directories:{test:"test"},dependencies:{commander:"^6.0.0"},devDependencies:{fibers:"^5.0.0",mocha:"^8.1.0"},scripts:{test:"mocha"}}});var Pe=G((St,Ee)=>{"use strict";var ze=pe(),j=he(),ke=ge(),Se=ye(),Y=20,xe=258,ve=0,Ne=1,Fe=2,Xe=6,Ge=50,Ke="314159265359",je="177245385090",Te=function(r,e){var t=r[e],n;for(n=e;n>0;n--)r[n]=r[n-1];return r[0]=t,t},g={OK:0,LAST_BLOCK:-1,NOT_BZIP_DATA:-2,UNEXPECTED_INPUT_EOF:-3,UNEXPECTED_OUTPUT_EOF:-4,DATA_ERROR:-5,OUT_OF_MEMORY:-6,OBSOLETE_INPUT:-7,END_OF_BLOCK:-8},I={};I[g.LAST_BLOCK]="Bad file checksum";I[g.NOT_BZIP_DATA]="Not bzip data";I[g.UNEXPECTED_INPUT_EOF]="Unexpected input EOF";I[g.UNEXPECTED_OUTPUT_EOF]="Unexpected output EOF";I[g.DATA_ERROR]="Data error";I[g.OUT_OF_MEMORY]="Out of memory";I[g.OBSOLETE_INPUT]="Obsolete (pre 0.9.5) bzip format not supported.";var T=function(r,e){var t=I[r]||"unknown error";e&&(t+=": "+e);var n=new TypeError(t);throw n.errorCode=r,n},S=function(r,e){this.writePos=this.writeCurrent=this.writeCount=0,this._start_bunzip(r,e)};S.prototype._init_block=function(){var r=this._get_next_block();return r?(this.blockCRC=new ke,!0):(this.writeCount=-1,!1)};S.prototype._start_bunzip=function(r,e){var t=new Buffer(4);(r.read(t,0,4)!==4||String.fromCharCode(t[0],t[1],t[2])!=="BZh")&&T(g.NOT_BZIP_DATA,"bad magic");var n=t[3]-48;(n<1||n>9)&&T(g.NOT_BZIP_DATA,"level out of range"),this.reader=new ze(r),this.dbufSize=1e5*n,this.nextoutput=0,this.outputStream=e,this.streamCRC=0};S.prototype._get_next_block=function(){var r,e,t,n=this.reader,i=n.pi();if(i===je)return!1;i!==Ke&&T(g.NOT_BZIP_DATA),this.targetBlockCRC=n.read(32)>>>0,this.streamCRC=(this.targetBlockCRC^(this.streamCRC<<1|this.streamCRC>>>31))>>>0,n.read(1)&&T(g.OBSOLETE_INPUT);var a=n.read(24);a>this.dbufSize&&T(g.DATA_ERROR,"initial position out of bounds");var o=n.read(16),s=new Buffer(256),c=0;for(r=0;r<16;r++)if(o&1<<15-r){var l=r*16;for(t=n.read(16),e=0;e<16;e++)t&1<<15-e&&(s[c++]=l+e)}var f=n.read(3);(f<Fe||f>Xe)&&T(g.DATA_ERROR);var u=n.read(15);u===0&&T(g.DATA_ERROR);var m=new Buffer(256);for(r=0;r<f;r++)m[r]=r;var b=new Buffer(u);for(r=0;r<u;r++){for(e=0;n.read(1);e++)e>=f&&T(g.DATA_ERROR);b[r]=Te(m,e)}var d=c+2,h=[],p;for(e=0;e<f;e++){var _=new Buffer(d),y=new Uint16Array(Y+1);for(o=n.read(5),r=0;r<d;r++){for(;(o<1||o>Y)&&T(g.DATA_ERROR),!!n.read(1);)n.read(1)?o--:o++;_[r]=o}var x,D;for(x=D=_[0],r=1;r<d;r++)_[r]>D?D=_[r]:_[r]<x&&(x=_[r]);p={},h.push(p),p.permute=new Uint16Array(xe),p.limit=new Uint32Array(Y+2),p.base=new Uint32Array(Y+1),p.minLen=x,p.maxLen=D;var A=0;for(r=x;r<=D;r++)for(y[r]=p.limit[r]=0,o=0;o<d;o++)_[o]===r&&(p.permute[A++]=o);for(r=0;r<d;r++)y[_[r]]++;for(A=o=0,r=x;r<D;r++)A+=y[r],p.limit[r]=A-1,A<<=1,o+=y[r],p.base[r+1]=A-o;p.limit[D+1]=Number.MAX_VALUE,p.limit[D]=A+y[D]-1,p.base[x]=0}var N=new Uint32Array(256);for(r=0;r<256;r++)m[r]=r;var M=0,C=0,le=0,E,F=this.dbuf=new Uint32Array(this.dbufSize);for(d=0;;){for(d--||(d=Ge-1,le>=u&&T(g.DATA_ERROR),p=h[b[le++]]),r=p.minLen,e=n.read(r);r>p.maxLen&&T(g.DATA_ERROR),!(e<=p.limit[r]);r++)e=e<<1|n.read(1);e-=p.base[r],(e<0||e>=xe)&&T(g.DATA_ERROR);var X=p.permute[e];if(X===ve||X===Ne){M||(M=1,o=0),X===ve?o+=M:o+=2*M,M<<=1;continue}if(M)for(M=0,C+o>this.dbufSize&&T(g.DATA_ERROR),E=s[m[0]],N[E]+=o;o--;)F[C++]=E;if(X>c)break;C>=this.dbufSize&&T(g.DATA_ERROR),r=X-1,E=Te(m,r),E=s[E],N[E]++,F[C++]=E}for((a<0||a>=C)&&T(g.DATA_ERROR),e=0,r=0;r<256;r++)t=e+N[r],N[r]=e,e=t;for(r=0;r<C;r++)E=F[r]&255,F[N[E]]|=r<<8,N[E]++;var Z=0,fe=0,de=0;return C&&(Z=F[a],fe=Z&255,Z>>=8,de=-1),this.writePos=Z,this.writeCurrent=fe,this.writeCount=C,this.writeRun=de,!0};S.prototype._read_bunzip=function(r,e){var t,n,i;if(this.writeCount<0)return 0;for(var a=0,o=this.dbuf,s=this.writePos,c=this.writeCurrent,l=this.writeCount,f=this.outputsize,u=this.writeRun;l;){for(l--,n=c,s=o[s],c=s&255,s>>=8,u++===3?(t=c,i=n,c=-1):(t=1,i=c),this.blockCRC.updateCRCRun(i,t);t--;)this.outputStream.writeByte(i),this.nextoutput++;c!=n&&(u=0)}return this.writeCount=l,this.blockCRC.getCRC()!==this.targetBlockCRC&&T(g.DATA_ERROR,"Bad block CRC (got "+this.blockCRC.getCRC().toString(16)+" expected "+this.targetBlockCRC.toString(16)+")"),this.nextoutput};var ne=function(r){if("readByte"in r)return r;var e=new j;return e.pos=0,e.readByte=function(){return r[this.pos++]},e.seek=function(t){this.pos=t},e.eof=function(){return this.pos>=r.length},e},we=function(r){var e=new j,t=!0;if(r)if(typeof r=="number")e.buffer=new Buffer(r),t=!1;else{if("writeByte"in r)return r;e.buffer=r,t=!1}else e.buffer=new Buffer(16384);return e.pos=0,e.writeByte=function(n){if(t&&this.pos>=this.buffer.length){var i=new Buffer(this.buffer.length*2);this.buffer.copy(i),this.buffer=i}this.buffer[this.pos++]=n},e.getBuffer=function(){if(this.pos!==this.buffer.length){if(!t)throw new TypeError("outputsize does not match decoded input");var n=new Buffer(this.pos);this.buffer.copy(n,0,0,this.pos),this.buffer=n}return this.buffer},e._coerced=!0,e};S.Err=g;S.decode=function(r,e,t){for(var n=ne(r),i=we(e),a=new S(n,i);!("eof"in n&&n.eof());)if(a._init_block())a._read_bunzip();else{var o=a.reader.read(32)>>>0;if(o!==a.streamCRC&&T(g.DATA_ERROR,"Bad stream CRC (got "+a.streamCRC.toString(16)+" expected "+o.toString(16)+")"),t&&"eof"in n&&!n.eof())a._start_bunzip(n,i);else break}if("getBuffer"in i)return i.getBuffer()};S.decodeBlock=function(r,e,t){var n=ne(r),i=we(t),a=new S(n,i);a.reader.seek(e);var o=a._get_next_block();if(o&&(a.blockCRC=new ke,a.writeCopies=0,a._read_bunzip()),"getBuffer"in i)return i.getBuffer()};S.table=function(r,e,t){var n=new j;n.delegate=ne(r),n.pos=0,n.readByte=function(){return this.pos++,this.delegate.readByte()},n.delegate.eof&&(n.eof=n.delegate.eof.bind(n.delegate));var i=new j;i.pos=0,i.writeByte=function(){this.pos++};for(var a=new S(n,i),o=a.dbufSize;!("eof"in n&&n.eof());){var s=n.pos*8+a.reader.bitOffset;if(a.reader.hasByte&&(s-=8),a._init_block()){var c=i.pos;a._read_bunzip(),e(s,i.pos-c)}else{var l=a.reader.read(32);if(t&&"eof"in n&&!n.eof())a._start_bunzip(n,i),console.assert(a.dbufSize===o,"shouldn't change block size within multistream file");else break}}};S.Stream=j;S.version=Se.version;S.license=Se.license;Ee.exports=S});import*as Be from"fs";import*as Q from"zlib";var Qe=Pe(),De=512,Ve=65536,We=16777216,$e=67108864,qe=2147483648,Ze={TABLE_OFFSET:0,HASH_A:1,HASH_B:2,TABLE:3};function Ye(){let r=1048577,e=new Uint32Array(256*5);for(let t=0;t<256;t++){let n=t;for(let i=0;i<5;i++){r=(r*125+3)%2796203;let a=(r&65535)<<16;r=(r*125+3)%2796203;let o=r&65535;e[n]=(a|o)>>>0,n+=256}}return e}var Re=Ye(),J=class{file;header;hashTable;blockTable;files;constructor(e,t=!0){if(Buffer.isBuffer(e)?this.file=e:this.file=Be.readFileSync(e),this.header=this.readHeader(),this.hashTable=this.readTable("hash"),this.blockTable=this.readTable("block"),t){let n=this.readFile("(listfile)");n?this.files=n.toString("utf8").trim().split(`\r
|
|
2
|
+
`):this.files=null}else this.files=null}readHeader(){let e=this.file.toString("utf8",0,4),t;if(e==="MPQ")t=this.readMPQHeader(),t.offset=0;else if(e==="MPQ\x1B"){let n=this.readMPQUserDataHeader();t=this.readMPQHeader(n.mpqHeaderOffset),t.offset=n.mpqHeaderOffset,t.userDataHeader=n}else throw new Error("Invalid MPQ file header");return t}readMPQHeader(e=0){let t=this.file.subarray(e,e+32),n={magic:t.toString("utf8",0,4),headerSize:t.readUInt32LE(4),archiveSize:t.readUInt32LE(8),formatVersion:t.readUInt16LE(12),sectorSizeShift:t.readUInt16LE(14),hashTableOffset:t.readUInt32LE(16),blockTableOffset:t.readUInt32LE(20),hashTableEntries:t.readUInt32LE(24),blockTableEntries:t.readUInt32LE(28)};if(n.formatVersion===1){let i=this.file.subarray(e+32,e+32+12);n.extendedBlockTableOffset=i.readUInt32LE(0)+i.readUInt32LE(4)*4294967296,n.hashTableOffsetHigh=i.readInt8(8),n.blockTableOffsetHigh=i.readInt8(10)}return n}readMPQUserDataHeader(){let e=this.file.subarray(0,16),t={magic:e.toString("utf8",0,4),userDataSize:e.readUInt32LE(4),mpqHeaderOffset:e.readUInt32LE(8),userDataHeaderSize:e.readUInt32LE(12)};return t.content=this.file.subarray(16,16+t.userDataHeaderSize),t}readTable(e){let t=e==="hash"?"hashTableOffset":"blockTableOffset",n=e==="hash"?"hashTableEntries":"blockTableEntries",i=this.header[t],a=this.header[n];if(i==null||a==null)throw new Error("Missing "+e+" offset or entries");let o=this.hash("("+e+" table)","TABLE"),s=this.file.subarray(i+(this.header.offset||0),i+(this.header.offset||0)+a*16);s=this.decrypt(s,o);let c=[];for(let l=0;l<a;l++){let f=s.subarray(l*16,l*16+16);e==="hash"?c.push({hashA:f.readUInt32LE(0),hashB:f.readUInt32LE(4),locale:f.readUInt16LE(8),platform:f.readUInt16LE(10),blockTableIndex:f.readUInt32LE(12)}):c.push({offset:f.readUInt32LE(0),archivedSize:f.readUInt32LE(4),size:f.readUInt32LE(8),flags:f.readUInt32LE(12)})}return c}getHashTableEntry(e){let t=this.hash(e,"HASH_A"),n=this.hash(e,"HASH_B");for(let i of this.hashTable)if(i.hashA===t&&i.hashB===n)return i}readFile(e,t=!1){function n(c){let l=c[0];if(l===0)return c;if(l===2)return Q.inflateSync(c.subarray(1));if(l===16)return Qe.decode(c.subarray(1));try{return Q.inflateSync(c.subarray(1))}catch{return Q.inflateRawSync(c.subarray(1))}}let i=this.getHashTableEntry(e);if(!i)return null;let a=this.blockTable[i.blockTableIndex];if(!a||!(a.flags&qe))return null;if(a.archivedSize===0)return Buffer.alloc(0);let o=a.offset+(this.header.offset||0),s=this.file.subarray(o,o+a.archivedSize);if(a.flags&Ve)throw new Error("Encryption is not supported");if(a.flags&We)a.flags&De&&(t||a.size>a.archivedSize)&&(s=n(s));else{let c=512<<this.header.sectorSizeShift,l=Math.trunc(a.size/c)+1,f=!1;a.flags&$e&&(f=!0,l+=1);let u=[];for(let h=0;h<l+1;h++)u.push(s.readUInt32LE(4*h));let m=u.length-(f?2:1),b=[],d=a.size;for(let h=0;h<m;h++){let p=s.subarray(u[h],u[h+1]);a.flags&De&&(t||d>p.length)&&(p=n(p)),d-=p.length,b.push(p)}s=Buffer.concat(b)}return s}hash(e,t){let n=2146271213,i=4008636142;for(let a=0;a<e.length;a++){let o=e.toUpperCase().charCodeAt(a);n=(Re[(Ze[t]<<8)+o]^n+i)>>>0,i=o+n+i+(i<<5)+3>>>0}return n}decrypt(e,t){let n=t>>>0,i=4008636142,a=Buffer.alloc(e.length),o=e.length/4;for(let s=0;s<o;s++){i=i+Re[1024+(n&255)]>>>0;let c=e.readUInt32LE(s*4);c=(c^n+i)>>>0,n=((~n<<21)+286331153|n>>>11)>>>0,i=c+i+(i<<5)+3>>>0,a.writeUInt32LE(c,s*4)}return a}};var V=class extends Error{constructor(e="Truncated Buffer"){super(e),this.name="TruncatedError"}},L=class extends Error{constructor(e="Corrupted Buffer"){super(e),this.name="CorruptedError"}},W=class{_data;_used;_next;_nextbits;_bigendian;constructor(e,t="big"){this._data=e,this._used=0,this._next=0,this._nextbits=0,this._bigendian=t==="big"}done(){return this._nextbits===0&&this._used>=this._data.length}used_bits(){return this._used*8-this._nextbits}byte_align(){this._nextbits=0}read_aligned_bytes(e){if(this.byte_align(),this._used+e>this._data.length)throw new V;let t=this._data.subarray(this._used,this._used+e);return this._used+=e,t}read_bits(e){let t=0,n=0;for(;n!==e;){if(this._nextbits===0){if(this.done())throw new V;this._next=this._data[this._used],this._used+=1,this._nextbits=8}let i=Math.min(e-n,this._nextbits),a=this._next&(1<<i)-1;this._bigendian?t+=a*Math.pow(2,e-n-i):t+=a*Math.pow(2,n),this._next>>=i,this._nextbits-=i,n+=i}return t}read_bits_bigint(e){let t=0n,n=0;for(;n!==e;){if(this._nextbits===0){if(this.done())throw new V;this._next=this._data[this._used],this._used+=1,this._nextbits=8}let i=Math.min(e-n,this._nextbits),a=BigInt(this._next&(1<<i)-1);this._bigendian?t|=a<<BigInt(e-n-i):t|=a<<BigInt(n),this._next>>=i,this._nextbits-=i,n+=i}return t}read_unaligned_bytes(e){let t=Buffer.alloc(e);for(let n=0;n<e;n++)t[n]=this.read_bits(8);return t}};var O=class{_buffer;_typeinfos;constructor(e,t){this._buffer=new W(e),this._typeinfos=t}instance(e){if(e>=this._typeinfos.length)throw new L(`Invalid typeid ${e}`);let t=this._typeinfos[e],n=t[0],i=t[1]||[],a=this[n];if(typeof a!="function")throw new Error(`Decoder method ${n} not implemented`);return a.apply(this,i)}byte_align(){this._buffer.byte_align()}done(){return this._buffer.done()}used_bits(){return this._buffer.used_bits()}_array(e,t){let n=this._int(e),i=new Array(n);for(let a=0;a<n;a++)i[a]=this.instance(t);return i}_bitarray(e){let t=this._int(e);return[t,this._buffer.read_bits(t)]}_blob(e){let t=this._int(e);return this._buffer.read_aligned_bytes(t)}_bool(){return this._int([0,1])!==0}_choice(e,t){let n=this._int(e);if(!(n in t))throw new L(`Choice tag ${n} not found`);let i=t[n];return{[i[0]]:this.instance(i[1])}}_fourcc(){let e=this._buffer.read_bits(32),t=Buffer.alloc(4);return t.writeUInt32BE(e,0),t.toString("ascii")}_int(e){return e[0]+this._buffer.read_bits(e[1])}_null(){return null}_optional(e){return this._bool()?this.instance(e):null}_real32(){return this._buffer.read_unaligned_bytes(4).readFloatBE(0)}_real64(){return this._buffer.read_unaligned_bytes(8).readDoubleBE(0)}_struct(e){let t={};for(let n of e)if(n[0]==="__parent"){let i=this.instance(n[1]);if(typeof i=="object"&&i!==null&&!Array.isArray(i)&&!Buffer.isBuffer(i))t={...t,...i};else{if(e.length===1)return i;t[n[0]]=i}}else t[n[0]]=this.instance(n[1]);return t}},P=class{_buffer;_typeinfos;constructor(e,t){this._buffer=new W(e),this._typeinfos=t}instance(e){if(e>=this._typeinfos.length)throw new L(`Invalid typeid ${e}`);let t=this._typeinfos[e],n=t[0],i=t[1]||[],a=this[n];if(typeof a!="function")throw new Error(`Decoder method ${n} not implemented`);return a.apply(this,i)}byte_align(){this._buffer.byte_align()}done(){return this._buffer.done()}used_bits(){return this._buffer.used_bits()}_expect_skip(e){if(this._buffer.read_bits(8)!==e)throw new L(`Expected skip ${e}`)}_vint(){let e=this._buffer.read_bits(8),t=(e&1)!==0,n=BigInt(e>>1&63),i=6n;for(;(e&128)!==0;)e=this._buffer.read_bits(8),n|=BigInt(e&127)<<i,i+=7n;let a=t?-n:n;return a>=BigInt(Number.MIN_SAFE_INTEGER)&&a<=BigInt(Number.MAX_SAFE_INTEGER)?Number(a):a}_array(e,t){this._expect_skip(0);let n=Number(this._vint()),i=new Array(n);for(let a=0;a<n;a++)i[a]=this.instance(t);return i}_bitarray(e){this._expect_skip(1);let t=Number(this._vint());return[t,this._buffer.read_aligned_bytes(Math.floor((t+7)/8))]}_blob(e){this._expect_skip(2);let t=Number(this._vint());return this._buffer.read_aligned_bytes(t)}_bool(){return this._expect_skip(6),this._buffer.read_bits(8)!==0}_choice(e,t){this._expect_skip(3);let n=Number(this._vint());if(!(n in t))return this._skip_instance(),{};let i=t[n];return{[i[0]]:this.instance(i[1])}}_fourcc(){return this._expect_skip(7),this._buffer.read_aligned_bytes(4)}_int(e){return this._expect_skip(9),Number(this._vint())}_null(){return null}_optional(e){return this._expect_skip(4),this._buffer.read_bits(8)!==0?this.instance(e):null}_real32(){return this._expect_skip(7),this._buffer.read_aligned_bytes(4).readFloatBE(0)}_real64(){return this._expect_skip(8),this._buffer.read_aligned_bytes(8).readDoubleBE(0)}_struct(e){this._expect_skip(5);let t={},n=Number(this._vint());for(let i=0;i<n;i++){let a=Number(this._vint()),o=e.find(s=>s[2]===a);if(o)if(o[0]==="__parent"){let s=this.instance(o[1]);typeof s=="object"&&s!==null&&!Array.isArray(s)&&!Buffer.isBuffer(s)?t={...t,...s}:e.length===1?t=s:t[o[0]]=s}else t[o[0]]=this.instance(o[1]);else this._skip_instance()}return t}_skip_instance(){let e=this._buffer.read_bits(8);if(e===0){let t=Number(this._vint());for(let n=0;n<t;n++)this._skip_instance()}else if(e===1){let t=Number(this._vint());this._buffer.read_aligned_bytes(Math.floor((t+7)/8))}else if(e===2){let t=Number(this._vint());this._buffer.read_aligned_bytes(t)}else if(e===3)this._vint(),this._skip_instance();else if(e===4)this._buffer.read_bits(8)!==0&&this._skip_instance();else if(e===5){let t=Number(this._vint());for(let n=0;n<t;n++)this._vint(),this._skip_instance()}else e===6?this._buffer.read_aligned_bytes(1):e===7?this._buffer.read_aligned_bytes(4):e===8?this._buffer.read_aligned_bytes(8):e===9&&this._vint()}};import $ from"fs";import U from"path";function Je(){let r=[];try{r.push(U.resolve(__dirname,"..","protocols")),r.push(U.resolve(__dirname,"..","..","protocols"))}catch{}r.push(U.resolve(process.cwd(),"protocols"));let e=process.cwd();for(;e!==U.dirname(e);){let t=U.join(e,"node_modules","@astefanski","storm-parser","protocols");r.push(t),e=U.dirname(e)}for(let t of r)if($.existsSync(t)&&$.readdirSync(t).some(n=>n.endsWith(".json")))return t;throw new Error(`@astefanski/storm-parser: Protocols directory not found. Did postinstall run? Try: npx tsx node_modules/@astefanski/storm-parser/scripts/postinstall.ts
|
|
3
|
+
Searched: `+r.join(", "))}var ie=new Map,ae=null;function Ce(){return ae||(ae=Je()),ae}function ee(r){if(ie.has(r))return ie.get(r);let e=Ce(),t=U.join(e,`protocol${r}.json`);if(!$.existsSync(t))return null;let n=JSON.parse($.readFileSync(t,"utf-8"));return ie.set(r,n),n}function te(){let r=Ce();return $.readdirSync(r).filter(e=>/^protocol\d+\.json$/.test(e)).map(e=>parseInt(e.match(/\d+/)[0],10)).sort((e,t)=>e-t)}var z=class{mpq;header;build=0;protocol;baseProtocol;constructor(e){e&&(this.mpq=new J(e,!1))}init(){let e=ee(29406);if(!e)throw new Error("Base protocol29406 not found. Did postinstall run? Try: npx tsx node_modules/@astefanski/storm-parser/scripts/postinstall.ts");this.baseProtocol=e;let t=this.mpq.header.userDataHeader;if(!t||!t.content)throw new Error("Replay does not have a user data header");let n=new P(t.content,this.baseProtocol.typeinfos);this.header=n.instance(this.baseProtocol.replay_header_typeid),this.build=this.header.m_version.m_baseBuild,this.protocol=this.loadProtocolForBuild(this.build)}loadProtocolForBuild(e){let t=ee(e);if(!t){let n=te(),i=n[0];for(let a of n)a<=e&&a>i&&(i=a);t=ee(i)}if(!t)throw new Error(`No protocol found for build ${e}`);return t}*decodeEventStream(e,t,n,i){if(!this.protocol)throw new Error("Protocol not loaded");let a=0;for(;!e.done();){let o=e.used_bits(),s=e.instance(this.protocol.svaruint32_typeid),c=Object.keys(s)[0],l=s[c];a+=l;let f=i?e.instance(this.protocol.replay_userid_typeid):void 0,u=Number(e.instance(t)),m=n[u];if(!m)throw new Error(`Unknown eventid(${u})`);let b=m[0],d=m[1],h=e.instance(b);h._event=d,h._eventid=u,h._gameloop=a,i&&(h._userid=f),e.byte_align(),h._bits=e.used_bits()-o,yield h}}getDetails(){if(!this.protocol)throw new Error("Protocol not loaded");let e=this.mpq.readFile("replay.details");return e?new P(e,this.protocol.typeinfos).instance(this.protocol.game_details_typeid):null}getInitData(){if(!this.protocol)throw new Error("Protocol not loaded");let e=this.mpq.readFile("replay.initData");return e?new O(e,this.protocol.typeinfos).instance(this.protocol.replay_initdata_typeid):null}getTrackerEvents(){if(!this.protocol)throw new Error("Protocol not loaded");let e=this.mpq.readFile("replay.tracker.events");if(!e)return[];let t=new P(e,this.protocol.typeinfos);return Array.from(this.decodeEventStream(t,this.protocol.tracker_eventid_typeid,this.protocol.tracker_event_types,!1))}getGameEvents(){if(!this.protocol)throw new Error("Protocol not loaded");let e=this.mpq.readFile("replay.game.events");if(!e)return[];let t=new O(e,this.protocol.typeinfos);return Array.from(this.decodeEventStream(t,this.protocol.game_eventid_typeid,this.protocol.game_event_types,!0))}getAttributeEvents(){if(!this.protocol)throw new Error("Protocol not loaded");let e=this.mpq.readFile("replay.attributes.events");return e?new P(e,this.protocol.typeinfos).instance(this.protocol.replay_attributes_events_typeid):null}extractFile(e){return this.mpq.readFile(e)}getHeader(){return this.header}getBuild(){return this.build}};var oe=class extends z{constructor(e){super();let t=e;if(!t){let n=te();t=n[n.length-1]}this.protocol=this.loadProtocolForBuild(t)}parseTracker(e){if(!this.protocol)return[];try{let t=new P(e,this.protocol.typeinfos);return Array.from(this.decodeEventStream(t,this.protocol.tracker_eventid_typeid,this.protocol.tracker_event_types,!1))}catch(t){return console.error("[LiveStreamParser] Failed to parse tracker events",t),[]}}parseGame(e){if(!this.protocol)return[];try{let t=new O(e,this.protocol.typeinfos);return Array.from(this.decodeEventStream(t,this.protocol.game_eventid_typeid,this.protocol.game_event_types,!0))}catch(t){return console.error("[LiveStreamParser] Failed to parse game events",t),[]}}parseDetails(e){if(!this.protocol)return null;try{return new P(e,this.protocol.typeinfos).instance(this.protocol.game_details_typeid)}catch(t){return console.error("[LiveStreamParser] Failed to parse details",t),null}}};var Ie=["Abathur","Alarak","Alexstrasza","Ana","Anduin","Anubarak","Artanis","Arthas","Auriel","Azmodan","Blaze","Brightwing","Cassia","Chen","Cho","Chromie","Deathwing","Deckard","Dehaka","Diablo","DVa","ETC","Falstad","Fenix","Gall","Garrosh","Gazlowe","Genji","Greymane","Guldan","Hanzo","Hogger","Illidan","Imperius","Jaina","Johanna","Junkrat","Kaelthas","KelThuzad","Kerrigan","Kharazim","Leoric","LiLi","LiMing","LtMorales","Lunara","Maiev","Malfurion","MalGanis","Malthael","Medivh","Mei","Mephisto","Muradin","Murky","Nazeebo","Nova","Orphea","Probius","Qhira","Ragnaros","Raynor","Rehgar","Rexxar","Samuro","SgtHammer","Sonya","Stitches","Stukov","Sylvanas","Tassadar","TheButcher","TheLostVikings","Thrall","Tracer","Tychus","Tyrael","Tyrande","Uther","Valeera","Valla","Varian","Whitemane","Xul","Yrel","Zagara","Zarya","Zeratul","Zuljin"],Ae={FaerieDragon:"Brightwing",Amazon:"Cassia",Barbarian:"Sonya",Crusader:"Johanna",DemonHunter:"Valla",WitchDoctor:"Nazeebo",Monk:"Kharazim",Wizard:"LiMing",Tinker:"Gazlowe",Medic:"LtMorales",L90ETC:"ETC",Butcher:"TheButcher",LostVikings:"TheLostVikings",Necromancer:"Xul",Dryad:"Lunara",Shapeshifter:"Greymane",ChoGall:"Cho"};function q(r){if(!r)return null;if(Ie.includes(r))return r;if(Ae[r])return Ae[r];let e=r.replace(/[^a-zA-Z0-9]/g,"").toLowerCase(),t=Ie.find(n=>n.toLowerCase()===e);return t||null}var Me={TownCannonTowerL2:"Fort Tower",TownCannonTowerL3:"Keep Tower",TownTownHallL2:"Fort",TownTownHallL3:"Keep",TownMoonwellL2:"Fort Well",TownMoonwellL3:"Keep Well"},et={MercLanerMeleeKnight:"Bruiser Camp",MercLanerRangedMage:"Bruiser Camp",MercLanerSiegeGiant:"Siege Camp",MercLanerRangedMinion:"Siege Camp"};function B(r){return Buffer.isBuffer(r)?r.toString("utf8"):typeof r=="string"?r:String(r??"")}function v(r,e){if(!r)return;let t=r.find(n=>B(n.m_key)===e);return t!==void 0?t.m_value:void 0}function re(r,e){if(!r)return;let t=r.find(n=>B(n.m_key)===e);return t!==void 0?B(t.m_value):void 0}function w(r,e){if(!r)return;let t=r.find(n=>B(n.m_key)===e);return t!==void 0?t.m_value:void 0}function se(r,e){return`${r}-${e}`}function R(r,e){return(r-e)/16}function He(r,e,t){let n={playerIDMap:{},loopGameStart:0,loopGameEnd:0,unitIndex:{},heroUnits:{},heroLives:{}};t.bans||(t.bans={0:[],1:[]}),t.levelTimes={0:{},1:{}},t.takedowns=[],t.structures={},t.XPBreakdown=[],t.mercs={captures:[],units:{}},t.objective={0:{count:0,events:[]},1:{count:0,events:[]},type:t.map||""};for(let i of r)switch(n.loopGameEnd=Math.max(n.loopGameEnd,i._gameloop),i._event){case"NNet.Replay.Tracker.SStatGameEvent":tt(i,n,e,t);break;case"NNet.Replay.Tracker.SHeroBannedEvent":if(i.m_hero){let a=B(i.m_hero),o=q(a);if(!o)break;let s=i.m_controllingTeam===2?1:0;if(t.bans&&t.bans[s]){let c=t.bans[s].length+1,l=t.bans[0].length+t.bans[1].length+1;t.bans[s].push({hero:o,order:c,absolute:l})}}break;case"NNet.Replay.Tracker.SUnitBornEvent":it(i,n,t);break;case"NNet.Replay.Tracker.SUnitDiedEvent":at(i,n,t);break;case"NNet.Replay.Tracker.SUnitOwnerChangeEvent":ot(i,n);break}return t.loopGameStart=n.loopGameStart,t.loopLength=n.loopGameEnd,t.length=(n.loopGameEnd-n.loopGameStart)/16,st(n,e),{playerIDMap:n.playerIDMap}}function tt(r,e,t,n){let i=B(r.m_eventName),a=r.m_intData,o=r.m_stringData,s=r.m_fixedData;switch(i){case"PlayerInit":{let c=v(a,"PlayerID"),l=re(o,"ToonHandle");c!==void 0&&l&&t[l]&&(e.playerIDMap[c]=l);break}case"GatesOpen":e.loopGameStart=r._gameloop;break;case"LevelUp":{let c=v(a,"PlayerID"),l=v(a,"Level");if(c===void 0||l===void 0)break;let f;if(c>=1&&c<=5)f="0";else if(c>=6&&c<=10)f="1";else break;n.levelTimes[f][String(l)]||(n.levelTimes[f][String(l)]={loop:r._gameloop,level:l,team:f,time:R(r._gameloop,e.loopGameStart)});break}case"TalentChosen":{let c=v(a,"PlayerID"),l=re(o,"PurchaseName");if(c===void 0||!l||l==="Win"||l==="Loss"||l.startsWith("Hero"))break;let f=n.map?.replace(/\s+/g,"")||"";if(l===f)break;let u=e.playerIDMap[c];if(!u||!t[u])break;let m=["Tier1Choice","Tier2Choice","Tier3Choice","Tier4Choice","Tier5Choice","Tier6Choice","Tier7Choice"];for(let b of m)if(!t[u].talents[b]){t[u].talents[b]=l;break}break}case"PlayerDeath":{let c=v(a,"PlayerID"),l=v(a,"KillingPlayer"),f=w(s,"PositionX")??0,u=w(s,"PositionY")??0;if(c===void 0)break;let m=e.playerIDMap[c];if(!m)break;let b={player:m,hero:t[m]?.hero||""},d=[],h=t[m]?.team;if(l&&l>0){let _=e.playerIDMap[l];_&&t[_]&&d.push({player:_,hero:t[_].hero})}for(let[_,y]of Object.entries(e.playerIDMap)){let x=t[y];!x||x.team===h||parseInt(_)===l||d.push({player:y,hero:x.hero})}let p={loop:r._gameloop,time:R(r._gameloop,e.loopGameStart),x:f,y:u,killers:d,victim:b};n.takedowns.push(p),t[m]&&t[m].deaths.push(p);for(let _ of d)t[_.player]&&t[_.player].takedowns.push(p);break}case"PeriodicXPBreakdown":{let c=v(a,"Team");if(c===void 0)break;let l={GameTime:v(a,"GameTime")??0,PreviousGameTime:v(a,"PreviousGameTime")??0,MinionXP:w(s,"MinionXP")??0,CreepXP:w(s,"CreepXP")??0,StructureXP:w(s,"StructureXP")??0,HeroXP:w(s,"HeroXP")??0,TrickleXP:w(s,"TrickleXP")??0};n.XPBreakdown.push({loop:r._gameloop,time:R(r._gameloop,e.loopGameStart),team:c,teamLevel:v(a,"TeamLevel")??0,breakdown:l,theoreticalMinionXP:v(a,"TheoreticalMinionXP")??0});break}case"EndOfGameXPBreakdown":{let c=v(a,"Team");if(c===void 0)break;n.XPBreakdown.push({loop:r._gameloop,time:R(r._gameloop,e.loopGameStart),team:c,theoreticalMinionXP:v(a,"TheoreticalMinionXP")??0,breakdown:{GameTime:0,PreviousGameTime:0,MinionXP:w(s,"MinionXP")??0,CreepXP:w(s,"CreepXP")??0,StructureXP:w(s,"StructureXP")??0,HeroXP:w(s,"HeroXP")??0,TrickleXP:w(s,"TrickleXP")??0}});break}case"JungleCampCapture":{let c=v(a,"CampTeam")??v(a,"Team")??0;n.mercs.captures.push({loop:r._gameloop,type:re(o,"CampType")??re(o,"Result")??"Unknown Camp",team:c,time:R(r._gameloop,e.loopGameStart)});break}case"EndOfGameTalentChoices":{let c=v(a,"PlayerID");if(c===void 0)break;let l=e.playerIDMap[c];if(!l||!t[l])break;let f={};if(o)for(let u of o){let m=B(u.m_key),b=B(u.m_value);m==="Tier 1 Choice"&&b?f.Tier1Choice=b:m==="Tier 2 Choice"&&b?f.Tier2Choice=b:m==="Tier 3 Choice"&&b?f.Tier3Choice=b:m==="Tier 4 Choice"&&b?f.Tier4Choice=b:m==="Tier 5 Choice"&&b?f.Tier5Choice=b:m==="Tier 6 Choice"&&b?f.Tier6Choice=b:m==="Tier 7 Choice"&&b&&(f.Tier7Choice=b)}t[l].talents=f;break}default:nt(i,r,e,n,a,s);break}}var rt=new Set(["SoulEatersSpawned","TributeCollected","RavenCurseActivated","AltarCaptured","SkyTempleShotsFired","DragonKnightActivated","GardenTerrorActivated","InfernalShrineCaptured","PunisherKilled","VolskayaVehicleCapture","BraxisWaveStart","ImmortalDefeated","NukeExploded","PayloadDelivered","AlteracCavalryCharge","AlteracCavalry"]);function nt(r,e,t,n,i,a){if(!rt.has(r)||!i)return;let o=v(i,"Team")??v(i,"Event")??0,s=o===0||o===1?o:0,c={team:o,loop:e._gameloop,time:R(e._gameloop,t.loopGameStart),score:v(i,"Score"),duration:w(a,"Duration")};n.objective[s].events.push(c),n.objective[s].count=n.objective[s].events.length}function it(r,e,t){let n=B(r.m_unitTypeName),i=r.m_unitTagIndex,a=r.m_unitTagRecycle,o=se(i,a),s=r.m_controlPlayerId??r.m_upkeepPlayerId,c=r.m_x??0,l=r.m_y??0,f;if(s>=1&&s<=5?f=0:s>=6&&s<=10?f=1:s===11?f=0:s===12?f=1:f=s<=5?0:1,e.unitIndex[o]={type:n,playerId:s,team:f,x:c,y:l,bornLoop:r._gameloop},n.startsWith("Town")&&Me[n]&&(t.structures[o]={type:n,name:Me[n],tag:i,rtag:a,x:c,y:l,team:f}),n.startsWith("Hero")&&s>=1&&s<=10){e.heroUnits[o]=s,e.heroLives[s]||(e.heroLives[s]=[]);let u=R(r._gameloop,e.loopGameStart);e.heroLives[s].push({born:u,locations:[{x:c,y:l,time:u}],duration:0})}if(et[n]){let m=t.mercs.captures[t.mercs.captures.length-1]?.loop??r._gameloop;t.mercs.units[o]={loop:m,team:f,type:n,locations:[{x:c,y:l}],time:R(m,e.loopGameStart),duration:0}}}function at(r,e,t){let n=se(r.m_unitTagIndex,r.m_unitTagRecycle),i=R(r._gameloop,e.loopGameStart);t.structures[n]&&(t.structures[n].destroyedLoop=r._gameloop,t.structures[n].destroyed=i),t.mercs.units[n]&&(t.mercs.units[n].duration=i-t.mercs.units[n].time);let a=e.heroUnits[n];if(a!==void 0&&e.heroLives[a]){let o=e.heroLives[a],s=o[o.length-1];s&&s.died===void 0&&(s.died=i,s.duration=i-s.born)}}function ot(r,e){let t=se(r.m_unitTagIndex,r.m_unitTagRecycle),n=r.m_controlPlayerId??r.m_upkeepPlayerId;e.unitIndex[t]&&(e.unitIndex[t].playerId=n,n>=1&&n<=5?e.unitIndex[t].team=0:n>=6&&n<=10&&(e.unitIndex[t].team=1))}function st(r,e){for(let[t,n]of Object.entries(r.heroLives)){let i=parseInt(t,10),a=r.playerIDMap[i];if(!a||!e[a])continue;for(let s of n)if(s.died===void 0){let c=s.locations[s.locations.length-1];s.duration=c?c.time-s.born:0}let o="";for(let[s,c]of Object.entries(r.heroUnits))if(c===i){o=s;break}o&&(e[a].units[o]={lives:n})}}var ct=["DamageTaken","CreepDamage","Healing","HeroDamage","MinionDamage","SelfHealing","SiegeDamage","ProtectionGivenToAllies","TeamfightDamageTaken","TeamfightHealingDone","TeamfightHeroDamage","TimeCCdEnemyHeroes","TimeRootingEnemyHeroes","TimeSpentDead","TimeStunningEnemyHeroes","TimeSilencingEnemyHeroes"];function lt(){return{DamageTaken:0,CreepDamage:0,Healing:0,HeroDamage:0,MinionDamage:0,SelfHealing:0,SiegeDamage:0,ProtectionGivenToAllies:0,TeamfightDamageTaken:0,TeamfightHealingDone:0,TeamfightHeroDamage:0,TimeCCdEnemyHeroes:0,TimeRootingEnemyHeroes:0,TimeSpentDead:0,TimeStunningEnemyHeroes:0,TimeSilencingEnemyHeroes:0,avgTimeSpentDead:0,timeDeadPct:0}}function ft(){return{mercCaptures:0,mercUptime:0,mercUptimePercent:0,structures:{},KDA:0,PPK:0,timeTo10:0,totals:lt(),levelAdvTime:0,maxLevelAdv:0,avgLevelAdv:0,levelAdvPct:0,uptime:[],uptimeHistogram:{},wipes:0,avgHeroesAlive:0,aces:0,timeWithHeroAdv:0,pctWithHeroAdv:0,passiveXPRate:0,passiveXPDiff:0,passiveXPGain:0}}function Oe(r,e){pt(r),dt(r,e),mt(r,e),bt(r),ht(r,e),gt(r)}function dt(r,e){for(let t of["0","1"]){let n=r.teams[t];if(!n)continue;n.names=[],n.heroes=[],n.tags=[],n.stats=ft();for(let u of n.ids){let m=e[u];m&&(n.names.push(m.name),n.heroes.push(m.hero),n.tags.push(m.tag))}for(let u of n.ids){let m=e[u];if(m)for(let b of ct){let d=m.gameStats[b];typeof d=="number"&&(n.stats.totals[b]+=d)}}let i=n.ids.reduce((u,m)=>u+(e[m]?.gameStats.Deaths??0),0);i>0&&(n.stats.totals.avgTimeSpentDead=n.stats.totals.TimeSpentDead/i),r.length>0&&(n.stats.totals.timeDeadPct=n.stats.totals.TimeSpentDead/(r.length*n.ids.length));let a=n.takedowns,o=i;n.stats.KDA=o>0?a/o:a,n.stats.PPK=a>0?r.takedowns.filter(u=>n.ids.includes(u.killers[0]?.player)).reduce((u,m)=>u+m.killers.length,0)/a:0;let s=r.levelTimes[t];s?.["10"]&&(n.stats.timeTo10=s[10].time);let c=parseInt(t,10),l=r.mercs.captures.filter(u=>u.team===c);n.stats.mercCaptures=l.length;let f=0;for(let u of Object.values(r.mercs.units))u.team===c&&u.duration>0&&(f+=u.duration);n.stats.mercUptime=f,n.stats.mercUptimePercent=r.length>0?f/r.length:0,ut(r,n,t)}}function ut(r,e,t){let n=parseInt(t,10),i=n===0?1:0,a={};for(let o of Object.values(r.structures)){let s=o.name;a[s]||(a[s]={lost:0,destroyed:0,first:r.length}),o.team===i&&o.destroyed!==void 0&&(a[s].destroyed++,a[s].first=Math.min(a[s].first,o.destroyed)),o.team===n&&o.destroyed!==void 0&&a[s].lost++}e.stats.structures=a}function mt(r,e){let t=r.length/60;for(let n of Object.values(e)){let i=n.gameStats,a=i.Deaths??0,o=i.TeamTakedowns??0;t>0&&(i.DPM=(i.HeroDamage??0)/t,i.HPM=((i.Healing??0)+(i.SelfHealing??0))/t,i.XPM=(i.ExperienceContribution??0)/t),i.KDA=a>0?(i.Takedowns??0)/a:i.Takedowns??0,i.KillParticipation=o>0?(i.Takedowns??0)/o:0,i.damageDonePerDeath=a>0?(i.HeroDamage??0)/a:i.HeroDamage??0,i.damageTakenPerDeath=a>0?(i.DamageTaken??0)/a:i.DamageTaken??0,i.healingDonePerDeath=a>0?((i.Healing??0)+(i.SelfHealing??0))/a:(i.Healing??0)+(i.SelfHealing??0),i.length=r.length}}function pt(r){let e=0,t=0,n=new Set(r.teams[0]?.ids||[]);for(let i of r.takedowns)n.has(i.victim.player)?t++:e++;r.team0Takedowns=e,r.team1Takedowns=t,r.teams[0]&&(r.teams[0].takedowns=e),r.teams[1]&&(r.teams[1].takedowns=t)}function bt(r){let e=r.levelTimes[0]||{},t=r.levelTimes[1]||{},n=[];for(let l of Object.values(e))n.push({time:l.time,team:0,level:l.level});for(let l of Object.values(t))n.push({time:l.time,team:1,level:l.level});if(n.sort((l,f)=>l.time-f.time),n.length===0){r.levelAdvTimeline=[];return}let i=[],a=0,o=0,s=n[0].time;for(let l of n){let f=a-o;l.time>s&&i.push({start:s,end:l.time,levelDiff:f,length:l.time-s}),l.team===0?a=l.level:o=l.level,s=l.time}let c=a-o;r.length>s&&i.push({start:s,end:r.length,levelDiff:c,length:r.length-s}),r.levelAdvTimeline=i;for(let l of["0","1"]){let f=r.teams[l];if(!f)continue;let u=l==="0"?1:-1,m=0,b=0,d=0,h=0;for(let p of i){let _=p.levelDiff*u;_>0&&(m+=p.length),b=Math.max(b,_),d+=_*p.length,h+=p.length}f.stats.levelAdvTime=m,f.stats.maxLevelAdv=b,f.stats.avgLevelAdv=h>0?d/h:0,f.stats.levelAdvPct=r.length>0?m/r.length:0}}function ht(r,e){for(let a of["0","1"]){let o=r.teams[a];if(!o)continue;let s=[];for(let p of o.ids){let _=e[p];if(_)for(let y of _.deaths){s.push({time:y.time,delta:-1});let x=y.time+_t(_.gameStats.Level??1);x<r.length&&s.push({time:x,delta:1})}}s.sort((p,_)=>p.time-_.time);let c=[{time:0,heroes:o.ids.length}],l=o.ids.length;for(let p of s)l+=p.delta,l=Math.max(0,Math.min(o.ids.length,l)),c.push({time:p.time,heroes:l});o.stats.uptime=c;let f={};for(let p=0;p<c.length;p++){let y=(p<c.length-1?c[p+1].time:r.length)-c[p].time,x=String(c[p].heroes);f[x]=(f[x]||0)+y}o.stats.uptimeHistogram=f;let u=0,m=0;for(let p=0;p<c.length;p++){let y=(p<c.length-1?c[p+1].time:r.length)-c[p].time;u+=c[p].heroes*y,m+=y}o.stats.avgHeroesAlive=m>0?u/m:o.ids.length,o.stats.wipes=c.filter(p=>p.heroes===0).length,o.stats.aces=0;let b=a==="0"?"1":"0",d=r.teams[b];d?.stats?.uptime&&(o.stats.aces=d.stats.uptime.filter(p=>p.heroes===0).length);let h=r.XPBreakdown.filter(p=>p.team===parseInt(a,10));if(h.length>0){let _=h[h.length-1].breakdown.TrickleXP;o.stats.passiveXPGain=_,o.stats.passiveXPRate=r.length>0?_/(r.length/60):0}}for(let a of["0","1"]){let o=r.teams[a],s=a==="0"?"1":"0",c=r.teams[s];if(!o||!c)continue;let l=o.stats.uptime,f=c.stats.uptime;if(!l.length||!f.length)continue;let u=new Set;for(let d of l)u.add(d.time);for(let d of f)u.add(d.time);let m=Array.from(u).sort((d,h)=>d-h),b=0;for(let d=0;d<m.length;d++){let h=m[d],_=(d<m.length-1?m[d+1]:r.length)-h,y=Le(l,h),x=Le(f,h);y>x&&(b+=_)}o.stats.timeWithHeroAdv=b,o.stats.pctWithHeroAdv=r.length>0?b/r.length:0}let t=r.teams[0]?.stats.passiveXPRate??0,n=r.teams[1]?.stats.passiveXPRate??0,i=(t+n)/2;r.teams[0]&&(r.teams[0].stats.passiveXPDiff=i>0?t/i:0),r.teams[1]&&(r.teams[1].stats.passiveXPDiff=i>0?n/i:0)}function Le(r,e){let t=0;for(let n of r)if(n.time<=e)t=n.heroes;else break;return t}function _t(r){return r<=1?15:r<=5?15+(r-1)*2:r<=10?23+(r-5)*3:r<=15?38+(r-10)*4:58+(r-15)*5}function gt(r){let e=1/0,t=-1,n=1/0,i=-1;for(let o of Object.values(r.structures))o.destroyed!==void 0&&(o.name==="Fort"&&o.destroyed<e&&(e=o.destroyed,t=o.team===0?1:0),o.name==="Keep"&&o.destroyed<n&&(n=o.destroyed,i=o.team===0?1:0));t>=0&&(r.firstFort=t,r.firstFortWin=t===r.winner),i>=0&&(r.firstKeep=i,r.firstKeepWin=i===r.winner);let a=[...r.objective[0].events.map(o=>({...o,assignedTeam:0})),...r.objective[1].events.map(o=>({...o,assignedTeam:1}))].sort((o,s)=>o.loop-s.loop);a.length>0&&(r.firstObjective=a[0].assignedTeam,r.firstObjectiveWin=a[0].assignedTeam===r.winner),r.firstPickWin=r.picks.first===r.winner}function k(r){return Buffer.isBuffer(r)?r.toString("utf8"):typeof r=="string"?r:String(r??"")}var ce=class{static async analyze(e){try{let t=new z(e);await t.init();let n=t.getDetails();if(!n)throw new Error("Missing replay.details from parsed MPQ archive");let i=t.getTrackerEvents(),a=t.getInitData(),s=t.getHeader()?.m_version??{},c={m_flags:s.m_flags??0,m_major:s.m_major??0,m_minor:s.m_minor??0,m_revision:s.m_revision??0,m_build:s.m_baseBuild??t.getBuild(),m_baseBuild:s.m_baseBuild??t.getBuild()},l=n.m_playerList.find(b=>b?.m_toon)?.m_toon,f={version:c,map:k(n.m_title),isBlizzardMap:n.m_isBlizzardMap,timeLocalOffset:Number(n.m_timeLocalOffset),gameSpeed:n.m_gameSpeed,date:this.fileTimeToDate(n.m_timeUTC).toISOString(),rawDate:Number(n.m_timeUTC),length:0,winner:-1,region:l?.m_region,playerIDs:[],heroes:[],levelTimes:{0:{},1:{}},bans:{0:[],1:[]},picks:{0:[],1:[],first:0},XPBreakdown:[],takedowns:[],mercs:{captures:[],units:{}},team0Takedowns:0,team1Takedowns:0,structures:{},objective:{0:{count:0,events:[]},1:{count:0,events:[]},type:""},teams:{0:this.emptyTeam(),1:this.emptyTeam()},winningPlayers:[],levelAdvTimeline:[],firstPickWin:!1};f.objective.type=f.map||"";let u={};for(let b of n.m_playerList){if(!b?.m_toon)continue;let d=b.m_toon,h=k(d.m_programId),p=`${d.m_region}-${h}-${d.m_realm}-${d.m_id}`,_=k(b.m_hero),y=q(_)||_;u[p]={hero:y,name:k(b.m_name),uuid:d.m_id,region:d.m_region,realm:d.m_realm,ToonHandle:p,tag:0,team:b.m_teamId,win:b.m_result===1,skin:"",mount:"",banner:"",spray:"",clanTag:"",highestLeague:0,combinedRaceLevels:0,randomSeed:0,announcer:"",silenced:!1,voiceSilenced:!1,gameStats:{},awards:[],talents:{},takedowns:[],deaths:[],units:{}},f.playerIDs.push(p),f.heroes.push(y)}this.extractBattleTags(t,n,u),this.extractDraft(a,f,n),this.extractCosmetics(a,n,u);let{playerIDMap:m}=He(i,u,f);this.processScoreEvents(i,m,u);for(let[b,d]of Object.entries(u)){d.win&&(f.winner=d.team,f.winningPlayers.push(b));let h=f.teams[d.team.toString()];h&&(h.level=Math.max(h.level,d.gameStats.Level||0),h.ids.push(b))}return Oe(f,u),{status:1,match:f,players:u}}catch(t){return console.error("ReplayAnalyzer Error:",t),{status:-2,error:String(t)}}}static emptyTeam(){return{level:0,takedowns:0,ids:[],names:[],heroes:[],tags:[],stats:{mercCaptures:0,mercUptime:0,mercUptimePercent:0,structures:{},KDA:0,PPK:0,timeTo10:0,totals:{DamageTaken:0,CreepDamage:0,Healing:0,HeroDamage:0,MinionDamage:0,SelfHealing:0,SiegeDamage:0,ProtectionGivenToAllies:0,TeamfightDamageTaken:0,TeamfightHealingDone:0,TeamfightHeroDamage:0,TimeCCdEnemyHeroes:0,TimeRootingEnemyHeroes:0,TimeSpentDead:0,TimeStunningEnemyHeroes:0,TimeSilencingEnemyHeroes:0,avgTimeSpentDead:0,timeDeadPct:0},levelAdvTime:0,maxLevelAdv:0,avgLevelAdv:0,levelAdvPct:0,uptime:[],uptimeHistogram:{},wipes:0,avgHeroesAlive:0,aces:0,timeWithHeroAdv:0,pctWithHeroAdv:0,passiveXPRate:0,passiveXPDiff:0,passiveXPGain:0}}}static extractBattleTags(e,t,n){let i=e.extractFile("replay.server.battlelobby");if(i)try{let a=new RegExp("([\\p{L}\\d]{3,24}#\\d{4,10})[z\xD8]?","gu"),o=i.toString("utf8").match(a);if(!o)return;let s=0;for(let c of t.m_playerList){if(!c?.m_toon)continue;let l=k(c.m_name);for(;s<o.length;){let u=o[s].split("#"),m=u[0],b=u[1].replace(/[zØ]/g,"");if(s++,m===l){let d=c.m_toon,h=`${d.m_region}-${k(d.m_programId)}-${d.m_realm}-${d.m_id}`;n[h]&&(n[h].tag=parseInt(b,10)||0);break}}}}catch(a){console.error("BattleTag regex error:",a)}}static extractDraft(e,t,n){if(e)try{let i=e.m_syncLobbyState;if(!i)return;let a=i.m_lobbyState,o=i.m_gameDescription;if(!a)return;o&&(t.randomValue=o.m_randomValue,t.gameOptions=o.m_gameOptions);let s=[],c=[];for(let d of n.m_playerList){if(!d?.m_toon)continue;let h=k(d.m_hero),p=q(h)||h;d.m_teamId===0?s.push(p):d.m_teamId===1&&c.push(p)}t.picks={0:s,1:c,first:0};let l,f=o?.m_gameOptions;if(f&&typeof f.m_ammId=="number"){let d=f.m_ammId;d===50001?l="Quick Match":d===50031?l="ARAM":d===50041?l="Unranked Draft":d===50051?l="Custom":d===50061?l="Hero League":d===50071?l="Team League":d===50091&&(l="Storm League")}if(!l&&typeof a.m_gameMode=="number"){let d=a.m_gameMode;d===3?l="Quick Match":d===4?l="Custom":d===5?l="Hero League":d===6?l="Team League":d===7?l="Unranked Draft":d===8&&(l="ARAM")}if(t.mode=l,typeof a.m_gameType=="number"&&(t.type=a.m_gameType),!a.m_slots)return;let m=a.m_pickedMapTag,b=0;m!==void 0&&(b=a.m_firstPickTeam??0,t.picks.first=b)}catch{}}static extractCosmetics(e,t,n){if(e)try{let i=e.m_syncLobbyState;if(!i)return;let a=i.m_lobbyState;if(!a)return;let o=a.m_slots,s=i.m_userInitialData;if(!o)return;let c=0;for(let l of t.m_playerList){if(!l?.m_toon)continue;let f=l.m_toon,u=`${f.m_region}-${k(f.m_programId)}-${f.m_realm}-${f.m_id}`,m=n[u];for(;c<o.length;){let b=o[c];c++;let d=b.m_hero;if(!(!d||Buffer.isBuffer(d)&&d.length===0)){if(m&&(m.skin=k(b.m_skin)||"",m.mount=k(b.m_mount)||"",m.announcer=k(b.m_announcerPack)||"",m.banner=k(b.m_banner)||"",m.spray=k(b.m_spray)||"",m.silenced=!!b.m_hasSilencePenalty,m.voiceSilenced=!!b.m_hasVoiceSilencePenalty,s)){let h=s.find(p=>k(p.m_name)===m.name);h&&(m.clanTag=k(h.m_clanTag),m.highestLeague=h.m_highestLeague,m.combinedRaceLevels=h.m_combinedRaceLevels,m.randomSeed=h.m_randomSeed)}break}}}}catch{}}static processScoreEvents(e,t,n){for(let i of e){if(i._event!=="NNet.Replay.Tracker.SScoreResultEvent")continue;let a=i.m_instanceList;for(let o of a){let s=k(o.m_name),c=o.m_values,l=s.startsWith("EndOfMatchAward"),f=0;for(let u of c)if(u&&u.length>0&&u[0]!==void 0){let m=f+1,b=t[m];if(b&&n[b]){let d=typeof u[0]=="object"&&u[0]!==null&&"m_value"in u[0]?u[0].m_value:u[0];d!=null&&(l?d===1&&n[b].awards.push(s):n[b].gameStats[s]=d)}f++}else u&&u.length===0&&f++}}}static fileTimeToDate(e){return new Date(Number(e)/1e4-116444736e5)}};export{oe as LiveStreamParser,ce as ReplayAnalyzer,z as ReplayParser};
|