meg4.js 374 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189
  1. // include: shell.js
  2. // The Module object: Our interface to the outside world. We import
  3. // and export values on it. There are various ways Module can be used:
  4. // 1. Not defined. We create it here
  5. // 2. A function parameter, function(moduleArg) => Promise<Module>
  6. // 3. pre-run appended it, var Module = {}; ..generated code..
  7. // 4. External script tag defines var Module.
  8. // We need to check if Module already exists (e.g. case 3 above).
  9. // Substitution will be replaced with actual code on later stage of the build,
  10. // this way Closure Compiler will not mangle it (e.g. case 4. above).
  11. // Note that if you want to run closure, and also to use Module
  12. // after the generated code, you will need to define var Module = {};
  13. // before the code. Then that object will be used in the code, and you
  14. // can continue to use Module afterwards as well.
  15. var Module = typeof Module != 'undefined' ? Module : {};
  16. // Determine the runtime environment we are in. You can customize this by
  17. // setting the ENVIRONMENT setting at compile time (see settings.js).
  18. // Attempt to auto-detect the environment
  19. var ENVIRONMENT_IS_WEB = typeof window == 'object';
  20. var ENVIRONMENT_IS_WORKER = typeof WorkerGlobalScope != 'undefined';
  21. // N.b. Electron.js environment is simultaneously a NODE-environment, but
  22. // also a web environment.
  23. var ENVIRONMENT_IS_NODE = typeof process == 'object' && typeof process.versions == 'object' && typeof process.versions.node == 'string' && process.type != 'renderer';
  24. var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
  25. if (ENVIRONMENT_IS_NODE) {
  26. // `require()` is no-op in an ESM module, use `createRequire()` to construct
  27. // the require()` function. This is only necessary for multi-environment
  28. // builds, `-sENVIRONMENT=node` emits a static import declaration instead.
  29. // TODO: Swap all `require()`'s with `import()`'s?
  30. }
  31. // --pre-jses are emitted after the Module integration code, so that they can
  32. // refer to Module (if they choose; they can also define Module)
  33. // include: /home/bzt/Documents/meg4/platform/emscripten/pre.js
  34. Module.canvas = document.getElementById("canvas");
  35. if(Module.canvas == undefined) Module.canvas = document.getElementByTagName("canvas");
  36. if(Module.canvas == undefined) alert("No canvas?");
  37. Module.canvas.addEventListener("contextmenu", function() {event.preventDefault()});
  38. Module.canvas.addEventListener("dragover", function() {event.preventDefault()});
  39. Module.canvas.addEventListener("drop", function() {meg4_openfile(event)});
  40. var tag = document.createElement("INPUT");
  41. tag.setAttribute("id", "meg4_upload");
  42. tag.setAttribute("type", "file");
  43. tag.setAttribute("style", "display:none");
  44. tag.addEventListener("change", function() {
  45. inp = document.getElementById("meg4_upload");
  46. if(inp.files.length>0) {
  47. var reader = new FileReader();
  48. reader.onloadend = function() { meg4_execute(inp.files[0].toString(), new Uint8Array(reader.result)); };
  49. reader.readAsArrayBuffer(inp.files[0]);
  50. }
  51. });
  52. document.body.appendChild(tag);
  53. tag = document.createElement("A");
  54. tag.setAttribute("id", "meg4_download");
  55. tag.setAttribute("style", "display:none");
  56. tag.setAttribute("download", "");
  57. document.body.appendChild(tag);
  58. function meg4_execute(name, data) {
  59. var base = name.split('/').pop();
  60. var file = new TextEncoder("utf-8").encode(base == undefined ? name : base);
  61. if(data != undefined && data.length > 0) {
  62. var meg4 = Module.cwrap("meg4_insert", "number", [ "number", "number", "number" ]);
  63. const fn = Module._malloc(file.length);
  64. const buf = Module._malloc(data.length);
  65. Module.HEAPU8.set(file, fn);
  66. Module.HEAPU8.set(data, buf);
  67. if(meg4 != undefined) meg4(fn, buf, data.length);
  68. Module._free(buf);
  69. Module._free(fn);
  70. }
  71. }
  72. function meg4_openfile(e) {
  73. e.stopPropagation();
  74. e.preventDefault();
  75. var floppy = e.dataTransfer.getData("url");
  76. if(floppy == undefined || floppy == "")
  77. floppy = e.dataTransfer.getData("src");
  78. if(floppy == undefined || floppy == "")
  79. floppy = new DOMParser().parseFromString(e.dataTransfer.getData('text/html'), "text/html").querySelector('img').src;
  80. if(floppy != undefined && floppy != "") {
  81. fetch(floppy).then((response) => {
  82. if(response.ok) response.arrayBuffer().then((buf) => { meg4_execute(floppy, new Uint8Array(buf)); });
  83. })
  84. .catch((error) => {
  85. var reader = new FileReader();
  86. reader.onloadend = function() { meg4_execute(floppy, new Uint8Array(reader.result)); };
  87. reader.readAsArrayBuffer(floppy);
  88. });
  89. }
  90. }
  91. function meg4_savefile(fn, fnlen, buf, len) {
  92. const fview = new Uint8Array(Module.HEAPU8.buffer,fn,fnlen);
  93. const bview = new Uint8Array(Module.HEAPU8.buffer,buf,len);
  94. var name = new TextDecoder("utf-8").decode(fview);
  95. var blob = new Blob([bview], { type: "application/octet-stream" });
  96. var url = window.URL.createObjectURL(blob);
  97. var a = document.getElementById('meg4_download');
  98. a.setAttribute('href',url);
  99. a.setAttribute('download', name != undefined ? name : "noname.png");
  100. a.click();
  101. window.URL.revokeObjectURL(url);
  102. }
  103. // end include: /home/bzt/Documents/meg4/platform/emscripten/pre.js
  104. // Sometimes an existing Module object exists with properties
  105. // meant to overwrite the default module functionality. Here
  106. // we collect those properties and reapply _after_ we configure
  107. // the current environment's defaults to avoid having to be so
  108. // defensive during initialization.
  109. var moduleOverrides = Object.assign({}, Module);
  110. var arguments_ = [];
  111. var thisProgram = './this.program';
  112. var quit_ = (status, toThrow) => {
  113. throw toThrow;
  114. };
  115. // `/` should be present at the end if `scriptDirectory` is not empty
  116. var scriptDirectory = '';
  117. function locateFile(path) {
  118. if (Module['locateFile']) {
  119. return Module['locateFile'](path, scriptDirectory);
  120. }
  121. return scriptDirectory + path;
  122. }
  123. // Hooks that are implemented differently in different runtime environments.
  124. var readAsync, readBinary;
  125. if (ENVIRONMENT_IS_NODE) {
  126. if (typeof process == 'undefined' || !process.release || process.release.name !== 'node') throw new Error('not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)');
  127. var nodeVersion = process.versions.node;
  128. var numericVersion = nodeVersion.split('.').slice(0, 3);
  129. numericVersion = (numericVersion[0] * 10000) + (numericVersion[1] * 100) + (numericVersion[2].split('-')[0] * 1);
  130. var minVersion = 160000;
  131. if (numericVersion < 160000) {
  132. throw new Error('This emscripten-generated code requires node v16.0.0 (detected v' + nodeVersion + ')');
  133. }
  134. // These modules will usually be used on Node.js. Load them eagerly to avoid
  135. // the complexity of lazy-loading.
  136. var fs = require('fs');
  137. var nodePath = require('path');
  138. scriptDirectory = __dirname + '/';
  139. // include: node_shell_read.js
  140. readBinary = (filename) => {
  141. // We need to re-wrap `file://` strings to URLs. Normalizing isn't
  142. // necessary in that case, the path should already be absolute.
  143. filename = isFileURI(filename) ? new URL(filename) : nodePath.normalize(filename);
  144. var ret = fs.readFileSync(filename);
  145. assert(ret.buffer);
  146. return ret;
  147. };
  148. readAsync = (filename, binary = true) => {
  149. // See the comment in the `readBinary` function.
  150. filename = isFileURI(filename) ? new URL(filename) : nodePath.normalize(filename);
  151. return new Promise((resolve, reject) => {
  152. fs.readFile(filename, binary ? undefined : 'utf8', (err, data) => {
  153. if (err) reject(err);
  154. else resolve(binary ? data.buffer : data);
  155. });
  156. });
  157. };
  158. // end include: node_shell_read.js
  159. if (!Module['thisProgram'] && process.argv.length > 1) {
  160. thisProgram = process.argv[1].replace(/\\/g, '/');
  161. }
  162. arguments_ = process.argv.slice(2);
  163. if (typeof module != 'undefined') {
  164. module['exports'] = Module;
  165. }
  166. quit_ = (status, toThrow) => {
  167. process.exitCode = status;
  168. throw toThrow;
  169. };
  170. } else
  171. if (ENVIRONMENT_IS_SHELL) {
  172. if ((typeof process == 'object' && typeof require === 'function') || typeof window == 'object' || typeof WorkerGlobalScope != 'undefined') throw new Error('not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)');
  173. } else
  174. // Note that this includes Node.js workers when relevant (pthreads is enabled).
  175. // Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and
  176. // ENVIRONMENT_IS_NODE.
  177. if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
  178. if (ENVIRONMENT_IS_WORKER) { // Check worker, not web, since window could be polyfilled
  179. scriptDirectory = self.location.href;
  180. } else if (typeof document != 'undefined' && document.currentScript) { // web
  181. scriptDirectory = document.currentScript.src;
  182. }
  183. // blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them.
  184. // otherwise, slice off the final part of the url to find the script directory.
  185. // if scriptDirectory does not contain a slash, lastIndexOf will return -1,
  186. // and scriptDirectory will correctly be replaced with an empty string.
  187. // If scriptDirectory contains a query (starting with ?) or a fragment (starting with #),
  188. // they are removed because they could contain a slash.
  189. if (scriptDirectory.startsWith('blob:')) {
  190. scriptDirectory = '';
  191. } else {
  192. scriptDirectory = scriptDirectory.substr(0, scriptDirectory.replace(/[?#].*/, '').lastIndexOf('/')+1);
  193. }
  194. if (!(typeof window == 'object' || typeof WorkerGlobalScope != 'undefined')) throw new Error('not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)');
  195. {
  196. // include: web_or_worker_shell_read.js
  197. if (ENVIRONMENT_IS_WORKER) {
  198. readBinary = (url) => {
  199. var xhr = new XMLHttpRequest();
  200. xhr.open('GET', url, false);
  201. xhr.responseType = 'arraybuffer';
  202. xhr.send(null);
  203. return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response));
  204. };
  205. }
  206. readAsync = (url) => {
  207. // Fetch has some additional restrictions over XHR, like it can't be used on a file:// url.
  208. // See https://github.com/github/fetch/pull/92#issuecomment-140665932
  209. // Cordova or Electron apps are typically loaded from a file:// url.
  210. // So use XHR on webview if URL is a file URL.
  211. if (isFileURI(url)) {
  212. return new Promise((resolve, reject) => {
  213. var xhr = new XMLHttpRequest();
  214. xhr.open('GET', url, true);
  215. xhr.responseType = 'arraybuffer';
  216. xhr.onload = () => {
  217. if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
  218. resolve(xhr.response);
  219. return;
  220. }
  221. reject(xhr.status);
  222. };
  223. xhr.onerror = reject;
  224. xhr.send(null);
  225. });
  226. }
  227. return fetch(url, { credentials: 'same-origin' })
  228. .then((response) => {
  229. if (response.ok) {
  230. return response.arrayBuffer();
  231. }
  232. return Promise.reject(new Error(response.status + ' : ' + response.url));
  233. })
  234. };
  235. // end include: web_or_worker_shell_read.js
  236. }
  237. } else
  238. {
  239. throw new Error('environment detection error');
  240. }
  241. var out = Module['print'] || console.log.bind(console);
  242. var err = Module['printErr'] || console.error.bind(console);
  243. // Merge back in the overrides
  244. Object.assign(Module, moduleOverrides);
  245. // Free the object hierarchy contained in the overrides, this lets the GC
  246. // reclaim data used.
  247. moduleOverrides = null;
  248. checkIncomingModuleAPI();
  249. // Emit code to handle expected values on the Module object. This applies Module.x
  250. // to the proper local x. This has two benefits: first, we only emit it if it is
  251. // expected to arrive, and second, by using a local everywhere else that can be
  252. // minified.
  253. if (Module['arguments']) arguments_ = Module['arguments'];legacyModuleProp('arguments', 'arguments_');
  254. if (Module['thisProgram']) thisProgram = Module['thisProgram'];legacyModuleProp('thisProgram', 'thisProgram');
  255. // perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message
  256. // Assertions on removed incoming Module JS APIs.
  257. assert(typeof Module['memoryInitializerPrefixURL'] == 'undefined', 'Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead');
  258. assert(typeof Module['pthreadMainPrefixURL'] == 'undefined', 'Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead');
  259. assert(typeof Module['cdInitializerPrefixURL'] == 'undefined', 'Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead');
  260. assert(typeof Module['filePackagePrefixURL'] == 'undefined', 'Module.filePackagePrefixURL option was removed, use Module.locateFile instead');
  261. assert(typeof Module['read'] == 'undefined', 'Module.read option was removed');
  262. assert(typeof Module['readAsync'] == 'undefined', 'Module.readAsync option was removed (modify readAsync in JS)');
  263. assert(typeof Module['readBinary'] == 'undefined', 'Module.readBinary option was removed (modify readBinary in JS)');
  264. assert(typeof Module['setWindowTitle'] == 'undefined', 'Module.setWindowTitle option was removed (modify emscripten_set_window_title in JS)');
  265. assert(typeof Module['TOTAL_MEMORY'] == 'undefined', 'Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY');
  266. legacyModuleProp('asm', 'wasmExports');
  267. legacyModuleProp('readAsync', 'readAsync');
  268. legacyModuleProp('readBinary', 'readBinary');
  269. legacyModuleProp('setWindowTitle', 'setWindowTitle');
  270. var IDBFS = 'IDBFS is no longer included by default; build with -lidbfs.js';
  271. var PROXYFS = 'PROXYFS is no longer included by default; build with -lproxyfs.js';
  272. var WORKERFS = 'WORKERFS is no longer included by default; build with -lworkerfs.js';
  273. var FETCHFS = 'FETCHFS is no longer included by default; build with -lfetchfs.js';
  274. var ICASEFS = 'ICASEFS is no longer included by default; build with -licasefs.js';
  275. var JSFILEFS = 'JSFILEFS is no longer included by default; build with -ljsfilefs.js';
  276. var OPFS = 'OPFS is no longer included by default; build with -lopfs.js';
  277. var NODEFS = 'NODEFS is no longer included by default; build with -lnodefs.js';
  278. assert(!ENVIRONMENT_IS_SHELL, 'shell environment detected but not enabled at build time. Add `shell` to `-sENVIRONMENT` to enable.');
  279. // end include: shell.js
  280. // include: preamble.js
  281. // === Preamble library stuff ===
  282. // Documentation for the public APIs defined in this file must be updated in:
  283. // site/source/docs/api_reference/preamble.js.rst
  284. // A prebuilt local version of the documentation is available at:
  285. // site/build/text/docs/api_reference/preamble.js.txt
  286. // You can also build docs locally as HTML or other formats in site/
  287. // An online HTML version (which may be of a different version of Emscripten)
  288. // is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html
  289. var wasmBinary = Module['wasmBinary'];legacyModuleProp('wasmBinary', 'wasmBinary');
  290. if (typeof WebAssembly != 'object') {
  291. err('no native wasm support detected');
  292. }
  293. // Wasm globals
  294. var wasmMemory;
  295. //========================================
  296. // Runtime essentials
  297. //========================================
  298. // whether we are quitting the application. no code should run after this.
  299. // set in exit() and abort()
  300. var ABORT = false;
  301. // set by exit() and abort(). Passed to 'onExit' handler.
  302. // NOTE: This is also used as the process return code code in shell environments
  303. // but only when noExitRuntime is false.
  304. var EXITSTATUS;
  305. // In STRICT mode, we only define assert() when ASSERTIONS is set. i.e. we
  306. // don't define it at all in release modes. This matches the behaviour of
  307. // MINIMAL_RUNTIME.
  308. // TODO(sbc): Make this the default even without STRICT enabled.
  309. /** @type {function(*, string=)} */
  310. function assert(condition, text) {
  311. if (!condition) {
  312. abort('Assertion failed' + (text ? ': ' + text : ''));
  313. }
  314. }
  315. // We used to include malloc/free by default in the past. Show a helpful error in
  316. // builds with assertions.
  317. // Memory management
  318. var HEAP,
  319. /** @type {!Int8Array} */
  320. HEAP8,
  321. /** @type {!Uint8Array} */
  322. HEAPU8,
  323. /** @type {!Int16Array} */
  324. HEAP16,
  325. /** @type {!Uint16Array} */
  326. HEAPU16,
  327. /** @type {!Int32Array} */
  328. HEAP32,
  329. /** @type {!Uint32Array} */
  330. HEAPU32,
  331. /** @type {!Float32Array} */
  332. HEAPF32,
  333. /* BigInt64Array type is not correctly defined in closure
  334. /** not-@type {!BigInt64Array} */
  335. HEAP64,
  336. /* BigUint64Array type is not correctly defined in closure
  337. /** not-t@type {!BigUint64Array} */
  338. HEAPU64,
  339. /** @type {!Float64Array} */
  340. HEAPF64;
  341. // include: runtime_shared.js
  342. function updateMemoryViews() {
  343. var b = wasmMemory.buffer;
  344. Module['HEAP8'] = HEAP8 = new Int8Array(b);
  345. Module['HEAP16'] = HEAP16 = new Int16Array(b);
  346. Module['HEAPU8'] = HEAPU8 = new Uint8Array(b);
  347. Module['HEAPU16'] = HEAPU16 = new Uint16Array(b);
  348. Module['HEAP32'] = HEAP32 = new Int32Array(b);
  349. Module['HEAPU32'] = HEAPU32 = new Uint32Array(b);
  350. Module['HEAPF32'] = HEAPF32 = new Float32Array(b);
  351. Module['HEAPF64'] = HEAPF64 = new Float64Array(b);
  352. Module['HEAP64'] = HEAP64 = new BigInt64Array(b);
  353. Module['HEAPU64'] = HEAPU64 = new BigUint64Array(b);
  354. }
  355. // end include: runtime_shared.js
  356. assert(!Module['STACK_SIZE'], 'STACK_SIZE can no longer be set at runtime. Use -sSTACK_SIZE at link time')
  357. assert(typeof Int32Array != 'undefined' && typeof Float64Array !== 'undefined' && Int32Array.prototype.subarray != undefined && Int32Array.prototype.set != undefined,
  358. 'JS engine does not provide full typed array support');
  359. // If memory is defined in wasm, the user can't provide it, or set INITIAL_MEMORY
  360. assert(!Module['wasmMemory'], 'Use of `wasmMemory` detected. Use -sIMPORTED_MEMORY to define wasmMemory externally');
  361. assert(!Module['INITIAL_MEMORY'], 'Detected runtime INITIAL_MEMORY setting. Use -sIMPORTED_MEMORY to define wasmMemory dynamically');
  362. // include: runtime_stack_check.js
  363. // Initializes the stack cookie. Called at the startup of main and at the startup of each thread in pthreads mode.
  364. function writeStackCookie() {
  365. var max = _emscripten_stack_get_end();
  366. assert((max & 3) == 0);
  367. // If the stack ends at address zero we write our cookies 4 bytes into the
  368. // stack. This prevents interference with SAFE_HEAP and ASAN which also
  369. // monitor writes to address zero.
  370. if (max == 0) {
  371. max += 4;
  372. }
  373. // The stack grow downwards towards _emscripten_stack_get_end.
  374. // We write cookies to the final two words in the stack and detect if they are
  375. // ever overwritten.
  376. HEAPU32[((max)>>2)] = 0x02135467;
  377. HEAPU32[(((max)+(4))>>2)] = 0x89BACDFE;
  378. // Also test the global address 0 for integrity.
  379. HEAPU32[((0)>>2)] = 1668509029;
  380. }
  381. function checkStackCookie() {
  382. if (ABORT) return;
  383. var max = _emscripten_stack_get_end();
  384. // See writeStackCookie().
  385. if (max == 0) {
  386. max += 4;
  387. }
  388. var cookie1 = HEAPU32[((max)>>2)];
  389. var cookie2 = HEAPU32[(((max)+(4))>>2)];
  390. if (cookie1 != 0x02135467 || cookie2 != 0x89BACDFE) {
  391. abort(`Stack overflow! Stack cookie has been overwritten at ${ptrToString(max)}, expected hex dwords 0x89BACDFE and 0x2135467, but received ${ptrToString(cookie2)} ${ptrToString(cookie1)}`);
  392. }
  393. // Also test the global address 0 for integrity.
  394. if (HEAPU32[((0)>>2)] != 0x63736d65 /* 'emsc' */) {
  395. abort('Runtime error: The application has corrupted its heap memory area (address zero)!');
  396. }
  397. }
  398. // end include: runtime_stack_check.js
  399. var __ATPRERUN__ = []; // functions called before the runtime is initialized
  400. var __ATINIT__ = []; // functions called during startup
  401. var __ATMAIN__ = []; // functions called when main() is to be run
  402. var __ATEXIT__ = []; // functions called during shutdown
  403. var __ATPOSTRUN__ = []; // functions called after the main() is called
  404. var runtimeInitialized = false;
  405. var runtimeExited = false;
  406. function preRun() {
  407. if (Module['preRun']) {
  408. if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];
  409. while (Module['preRun'].length) {
  410. addOnPreRun(Module['preRun'].shift());
  411. }
  412. }
  413. callRuntimeCallbacks(__ATPRERUN__);
  414. }
  415. function initRuntime() {
  416. assert(!runtimeInitialized);
  417. runtimeInitialized = true;
  418. checkStackCookie();
  419. if (!Module['noFSInit'] && !FS.initialized)
  420. FS.init();
  421. FS.ignorePermissions = false;
  422. TTY.init();
  423. callRuntimeCallbacks(__ATINIT__);
  424. }
  425. function preMain() {
  426. checkStackCookie();
  427. callRuntimeCallbacks(__ATMAIN__);
  428. }
  429. function exitRuntime() {
  430. assert(!runtimeExited);
  431. checkStackCookie();
  432. ___funcs_on_exit(); // Native atexit() functions
  433. callRuntimeCallbacks(__ATEXIT__);
  434. FS.quit();
  435. TTY.shutdown();
  436. runtimeExited = true;
  437. }
  438. function postRun() {
  439. checkStackCookie();
  440. if (Module['postRun']) {
  441. if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];
  442. while (Module['postRun'].length) {
  443. addOnPostRun(Module['postRun'].shift());
  444. }
  445. }
  446. callRuntimeCallbacks(__ATPOSTRUN__);
  447. }
  448. function addOnPreRun(cb) {
  449. __ATPRERUN__.unshift(cb);
  450. }
  451. function addOnInit(cb) {
  452. __ATINIT__.unshift(cb);
  453. }
  454. function addOnPreMain(cb) {
  455. __ATMAIN__.unshift(cb);
  456. }
  457. function addOnExit(cb) {
  458. __ATEXIT__.unshift(cb);
  459. }
  460. function addOnPostRun(cb) {
  461. __ATPOSTRUN__.unshift(cb);
  462. }
  463. // include: runtime_math.js
  464. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul
  465. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround
  466. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32
  467. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc
  468. assert(Math.imul, 'This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
  469. assert(Math.fround, 'This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
  470. assert(Math.clz32, 'This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
  471. assert(Math.trunc, 'This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
  472. // end include: runtime_math.js
  473. // A counter of dependencies for calling run(). If we need to
  474. // do asynchronous work before running, increment this and
  475. // decrement it. Incrementing must happen in a place like
  476. // Module.preRun (used by emcc to add file preloading).
  477. // Note that you can add dependencies in preRun, even though
  478. // it happens right before run - run will be postponed until
  479. // the dependencies are met.
  480. var runDependencies = 0;
  481. var runDependencyWatcher = null;
  482. var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled
  483. var runDependencyTracking = {};
  484. function getUniqueRunDependency(id) {
  485. var orig = id;
  486. while (1) {
  487. if (!runDependencyTracking[id]) return id;
  488. id = orig + Math.random();
  489. }
  490. }
  491. function addRunDependency(id) {
  492. runDependencies++;
  493. Module['monitorRunDependencies']?.(runDependencies);
  494. if (id) {
  495. assert(!runDependencyTracking[id]);
  496. runDependencyTracking[id] = 1;
  497. if (runDependencyWatcher === null && typeof setInterval != 'undefined') {
  498. // Check for missing dependencies every few seconds
  499. runDependencyWatcher = setInterval(() => {
  500. if (ABORT) {
  501. clearInterval(runDependencyWatcher);
  502. runDependencyWatcher = null;
  503. return;
  504. }
  505. var shown = false;
  506. for (var dep in runDependencyTracking) {
  507. if (!shown) {
  508. shown = true;
  509. err('still waiting on run dependencies:');
  510. }
  511. err(`dependency: ${dep}`);
  512. }
  513. if (shown) {
  514. err('(end of list)');
  515. }
  516. }, 10000);
  517. }
  518. } else {
  519. err('warning: run dependency added without ID');
  520. }
  521. }
  522. function removeRunDependency(id) {
  523. runDependencies--;
  524. Module['monitorRunDependencies']?.(runDependencies);
  525. if (id) {
  526. assert(runDependencyTracking[id]);
  527. delete runDependencyTracking[id];
  528. } else {
  529. err('warning: run dependency removed without ID');
  530. }
  531. if (runDependencies == 0) {
  532. if (runDependencyWatcher !== null) {
  533. clearInterval(runDependencyWatcher);
  534. runDependencyWatcher = null;
  535. }
  536. if (dependenciesFulfilled) {
  537. var callback = dependenciesFulfilled;
  538. dependenciesFulfilled = null;
  539. callback(); // can add another dependenciesFulfilled
  540. }
  541. }
  542. }
  543. /** @param {string|number=} what */
  544. function abort(what) {
  545. Module['onAbort']?.(what);
  546. what = 'Aborted(' + what + ')';
  547. // TODO(sbc): Should we remove printing and leave it up to whoever
  548. // catches the exception?
  549. err(what);
  550. ABORT = true;
  551. // Use a wasm runtime error, because a JS error might be seen as a foreign
  552. // exception, which means we'd run destructors on it. We need the error to
  553. // simply make the program stop.
  554. // FIXME This approach does not work in Wasm EH because it currently does not assume
  555. // all RuntimeErrors are from traps; it decides whether a RuntimeError is from
  556. // a trap or not based on a hidden field within the object. So at the moment
  557. // we don't have a way of throwing a wasm trap from JS. TODO Make a JS API that
  558. // allows this in the wasm spec.
  559. // Suppress closure compiler warning here. Closure compiler's builtin extern
  560. // definition for WebAssembly.RuntimeError claims it takes no arguments even
  561. // though it can.
  562. // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure gets fixed.
  563. /** @suppress {checkTypes} */
  564. var e = new WebAssembly.RuntimeError(what);
  565. // Throw the error whether or not MODULARIZE is set because abort is used
  566. // in code paths apart from instantiation where an exception is expected
  567. // to be thrown when abort is called.
  568. throw e;
  569. }
  570. // include: memoryprofiler.js
  571. // end include: memoryprofiler.js
  572. // include: URIUtils.js
  573. // Prefix of data URIs emitted by SINGLE_FILE and related options.
  574. var dataURIPrefix = 'data:application/octet-stream;base64,';
  575. /**
  576. * Indicates whether filename is a base64 data URI.
  577. * @noinline
  578. */
  579. var isDataURI = (filename) => filename.startsWith(dataURIPrefix);
  580. /**
  581. * Indicates whether filename is delivered via file protocol (as opposed to http/https)
  582. * @noinline
  583. */
  584. var isFileURI = (filename) => filename.startsWith('file://');
  585. // end include: URIUtils.js
  586. function createExportWrapper(name, nargs) {
  587. return (...args) => {
  588. assert(runtimeInitialized, `native function \`${name}\` called before runtime initialization`);
  589. assert(!runtimeExited, `native function \`${name}\` called after runtime exit (use NO_EXIT_RUNTIME to keep it alive after main() exits)`);
  590. var f = wasmExports[name];
  591. assert(f, `exported native function \`${name}\` not found`);
  592. // Only assert for too many arguments. Too few can be valid since the missing arguments will be zero filled.
  593. assert(args.length <= nargs, `native function \`${name}\` called with ${args.length} args but expects ${nargs}`);
  594. return f(...args);
  595. };
  596. }
  597. // include: runtime_exceptions.js
  598. // end include: runtime_exceptions.js
  599. function findWasmBinary() {
  600. var f = 'meg4.wasm';
  601. if (!isDataURI(f)) {
  602. return locateFile(f);
  603. }
  604. return f;
  605. }
  606. var wasmBinaryFile;
  607. function getBinarySync(file) {
  608. if (file == wasmBinaryFile && wasmBinary) {
  609. return new Uint8Array(wasmBinary);
  610. }
  611. if (readBinary) {
  612. return readBinary(file);
  613. }
  614. throw 'both async and sync fetching of the wasm failed';
  615. }
  616. function getBinaryPromise(binaryFile) {
  617. // If we don't have the binary yet, load it asynchronously using readAsync.
  618. if (!wasmBinary
  619. ) {
  620. // Fetch the binary using readAsync
  621. return readAsync(binaryFile).then(
  622. (response) => new Uint8Array(/** @type{!ArrayBuffer} */(response)),
  623. // Fall back to getBinarySync if readAsync fails
  624. () => getBinarySync(binaryFile)
  625. );
  626. }
  627. // Otherwise, getBinarySync should be able to get it synchronously
  628. return Promise.resolve().then(() => getBinarySync(binaryFile));
  629. }
  630. function instantiateArrayBuffer(binaryFile, imports, receiver) {
  631. return getBinaryPromise(binaryFile).then((binary) => {
  632. return WebAssembly.instantiate(binary, imports);
  633. }).then(receiver, (reason) => {
  634. err(`failed to asynchronously prepare wasm: ${reason}`);
  635. // Warn on some common problems.
  636. if (isFileURI(wasmBinaryFile)) {
  637. err(`warning: Loading from a file URI (${wasmBinaryFile}) is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing`);
  638. }
  639. abort(reason);
  640. });
  641. }
  642. function instantiateAsync(binary, binaryFile, imports, callback) {
  643. if (!binary &&
  644. typeof WebAssembly.instantiateStreaming == 'function' &&
  645. !isDataURI(binaryFile) &&
  646. // Don't use streaming for file:// delivered objects in a webview, fetch them synchronously.
  647. !isFileURI(binaryFile) &&
  648. // Avoid instantiateStreaming() on Node.js environment for now, as while
  649. // Node.js v18.1.0 implements it, it does not have a full fetch()
  650. // implementation yet.
  651. //
  652. // Reference:
  653. // https://github.com/emscripten-core/emscripten/pull/16917
  654. !ENVIRONMENT_IS_NODE &&
  655. typeof fetch == 'function') {
  656. return fetch(binaryFile, { credentials: 'same-origin' }).then((response) => {
  657. // Suppress closure warning here since the upstream definition for
  658. // instantiateStreaming only allows Promise<Repsponse> rather than
  659. // an actual Response.
  660. // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure is fixed.
  661. /** @suppress {checkTypes} */
  662. var result = WebAssembly.instantiateStreaming(response, imports);
  663. return result.then(
  664. callback,
  665. function(reason) {
  666. // We expect the most common failure cause to be a bad MIME type for the binary,
  667. // in which case falling back to ArrayBuffer instantiation should work.
  668. err(`wasm streaming compile failed: ${reason}`);
  669. err('falling back to ArrayBuffer instantiation');
  670. return instantiateArrayBuffer(binaryFile, imports, callback);
  671. });
  672. });
  673. }
  674. return instantiateArrayBuffer(binaryFile, imports, callback);
  675. }
  676. function getWasmImports() {
  677. // prepare imports
  678. return {
  679. 'env': wasmImports,
  680. 'wasi_snapshot_preview1': wasmImports,
  681. }
  682. }
  683. // Create the wasm instance.
  684. // Receives the wasm imports, returns the exports.
  685. function createWasm() {
  686. // Load the wasm module and create an instance of using native support in the JS engine.
  687. // handle a generated wasm instance, receiving its exports and
  688. // performing other necessary setup
  689. /** @param {WebAssembly.Module=} module*/
  690. function receiveInstance(instance, module) {
  691. wasmExports = instance.exports;
  692. wasmMemory = wasmExports['memory'];
  693. assert(wasmMemory, 'memory not found in wasm exports');
  694. updateMemoryViews();
  695. wasmTable = wasmExports['__indirect_function_table'];
  696. assert(wasmTable, 'table not found in wasm exports');
  697. addOnInit(wasmExports['__wasm_call_ctors']);
  698. removeRunDependency('wasm-instantiate');
  699. return wasmExports;
  700. }
  701. // wait for the pthread pool (if any)
  702. addRunDependency('wasm-instantiate');
  703. // Prefer streaming instantiation if available.
  704. // Async compilation can be confusing when an error on the page overwrites Module
  705. // (for example, if the order of elements is wrong, and the one defining Module is
  706. // later), so we save Module and check it later.
  707. var trueModule = Module;
  708. function receiveInstantiationResult(result) {
  709. // 'result' is a ResultObject object which has both the module and instance.
  710. // receiveInstance() will swap in the exports (to Module.asm) so they can be called
  711. assert(Module === trueModule, 'the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?');
  712. trueModule = null;
  713. // TODO: Due to Closure regression https://github.com/google/closure-compiler/issues/3193, the above line no longer optimizes out down to the following line.
  714. // When the regression is fixed, can restore the above PTHREADS-enabled path.
  715. receiveInstance(result['instance']);
  716. }
  717. var info = getWasmImports();
  718. // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback
  719. // to manually instantiate the Wasm module themselves. This allows pages to
  720. // run the instantiation parallel to any other async startup actions they are
  721. // performing.
  722. // Also pthreads and wasm workers initialize the wasm instance through this
  723. // path.
  724. if (Module['instantiateWasm']) {
  725. try {
  726. return Module['instantiateWasm'](info, receiveInstance);
  727. } catch(e) {
  728. err(`Module.instantiateWasm callback failed with error: ${e}`);
  729. return false;
  730. }
  731. }
  732. wasmBinaryFile ??= findWasmBinary();
  733. instantiateAsync(wasmBinary, wasmBinaryFile, info, receiveInstantiationResult);
  734. return {}; // no exports yet; we'll fill them in later
  735. }
  736. // include: runtime_debug.js
  737. // Endianness check
  738. (() => {
  739. var h16 = new Int16Array(1);
  740. var h8 = new Int8Array(h16.buffer);
  741. h16[0] = 0x6373;
  742. if (h8[0] !== 0x73 || h8[1] !== 0x63) throw 'Runtime error: expected the system to be little-endian! (Run with -sSUPPORT_BIG_ENDIAN to bypass)';
  743. })();
  744. if (Module['ENVIRONMENT']) {
  745. throw new Error('Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -sENVIRONMENT=web or -sENVIRONMENT=node)');
  746. }
  747. function legacyModuleProp(prop, newName, incoming=true) {
  748. if (!Object.getOwnPropertyDescriptor(Module, prop)) {
  749. Object.defineProperty(Module, prop, {
  750. configurable: true,
  751. get() {
  752. let extra = incoming ? ' (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)' : '';
  753. abort(`\`Module.${prop}\` has been replaced by \`${newName}\`` + extra);
  754. }
  755. });
  756. }
  757. }
  758. function ignoredModuleProp(prop) {
  759. if (Object.getOwnPropertyDescriptor(Module, prop)) {
  760. abort(`\`Module.${prop}\` was supplied but \`${prop}\` not included in INCOMING_MODULE_JS_API`);
  761. }
  762. }
  763. // forcing the filesystem exports a few things by default
  764. function isExportedByForceFilesystem(name) {
  765. return name === 'FS_createPath' ||
  766. name === 'FS_createDataFile' ||
  767. name === 'FS_createPreloadedFile' ||
  768. name === 'FS_unlink' ||
  769. name === 'addRunDependency' ||
  770. // The old FS has some functionality that WasmFS lacks.
  771. name === 'FS_createLazyFile' ||
  772. name === 'FS_createDevice' ||
  773. name === 'removeRunDependency';
  774. }
  775. /**
  776. * Intercept access to a global symbol. This enables us to give informative
  777. * warnings/errors when folks attempt to use symbols they did not include in
  778. * their build, or no symbols that no longer exist.
  779. */
  780. function hookGlobalSymbolAccess(sym, func) {
  781. if (typeof globalThis != 'undefined' && !Object.getOwnPropertyDescriptor(globalThis, sym)) {
  782. Object.defineProperty(globalThis, sym, {
  783. configurable: true,
  784. get() {
  785. func();
  786. return undefined;
  787. }
  788. });
  789. }
  790. }
  791. function missingGlobal(sym, msg) {
  792. hookGlobalSymbolAccess(sym, () => {
  793. warnOnce(`\`${sym}\` is not longer defined by emscripten. ${msg}`);
  794. });
  795. }
  796. missingGlobal('buffer', 'Please use HEAP8.buffer or wasmMemory.buffer');
  797. missingGlobal('asm', 'Please use wasmExports instead');
  798. function missingLibrarySymbol(sym) {
  799. hookGlobalSymbolAccess(sym, () => {
  800. // Can't `abort()` here because it would break code that does runtime
  801. // checks. e.g. `if (typeof SDL === 'undefined')`.
  802. var msg = `\`${sym}\` is a library symbol and not included by default; add it to your library.js __deps or to DEFAULT_LIBRARY_FUNCS_TO_INCLUDE on the command line`;
  803. // DEFAULT_LIBRARY_FUNCS_TO_INCLUDE requires the name as it appears in
  804. // library.js, which means $name for a JS name with no prefix, or name
  805. // for a JS name like _name.
  806. var librarySymbol = sym;
  807. if (!librarySymbol.startsWith('_')) {
  808. librarySymbol = '$' + sym;
  809. }
  810. msg += ` (e.g. -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE='${librarySymbol}')`;
  811. if (isExportedByForceFilesystem(sym)) {
  812. msg += '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you';
  813. }
  814. warnOnce(msg);
  815. });
  816. // Any symbol that is not included from the JS library is also (by definition)
  817. // not exported on the Module object.
  818. unexportedRuntimeSymbol(sym);
  819. }
  820. function unexportedRuntimeSymbol(sym) {
  821. if (!Object.getOwnPropertyDescriptor(Module, sym)) {
  822. Object.defineProperty(Module, sym, {
  823. configurable: true,
  824. get() {
  825. var msg = `'${sym}' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the Emscripten FAQ)`;
  826. if (isExportedByForceFilesystem(sym)) {
  827. msg += '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you';
  828. }
  829. abort(msg);
  830. }
  831. });
  832. }
  833. }
  834. // Used by XXXXX_DEBUG settings to output debug messages.
  835. function dbg(...args) {
  836. // TODO(sbc): Make this configurable somehow. Its not always convenient for
  837. // logging to show up as warnings.
  838. console.warn(...args);
  839. }
  840. // end include: runtime_debug.js
  841. // === Body ===
  842. var ASM_CONSTS = {
  843. 3955176: () => { document.getElementById('meg4_upload').click(); },
  844. 3955228: ($0, $1, $2, $3) => { meg4_savefile($0, $1, $2, $3); },
  845. 3955263: ($0, $1, $2, $3) => { var name = new TextDecoder("utf-8").decode(new Uint8Array(Module.HEAPU8.buffer,$0,$1)); var data = new TextDecoder("utf-8").decode(new Uint8Array(Module.HEAPU8.buffer,$2,$3)); localStorage.setItem("MEG-4/"+name, data); },
  846. 3955486: ($0, $1) => { var name = new TextDecoder("utf-8").decode(new Uint8Array(Module.HEAPU8.buffer,$0,$1)); var data = localStorage.getItem("MEG-4/"+name); if(data != undefined) { const buf = Module._malloc(data.length + 1); Module.HEAPU8.set(new TextEncoder("utf-8").encode(data + String.fromCharCode(0)), buf); return buf; } return 0; },
  847. 3955807: () => { var ln=document.location.href.split('?')[1];if(ln==undefined)ln=navigator.language.substr(0,2); return ln.charCodeAt(1) * 256 + ln.charCodeAt(0); },
  848. 3955957: () => { return Module.canvas.width; },
  849. 3955989: () => { return Module.canvas.height; },
  850. 3956022: ($0) => { var str = UTF8ToString($0) + '\n\n' + 'Abort/Retry/Ignore/AlwaysIgnore? [ariA] :'; var reply = window.prompt(str, "i"); if (reply === null) { reply = "i"; } return allocate(intArrayFromString(reply), 'i8', ALLOC_NORMAL); },
  851. 3956247: () => { if (typeof(AudioContext) !== 'undefined') { return true; } else if (typeof(webkitAudioContext) !== 'undefined') { return true; } return false; },
  852. 3956394: () => { if ((typeof(navigator.mediaDevices) !== 'undefined') && (typeof(navigator.mediaDevices.getUserMedia) !== 'undefined')) { return true; } else if (typeof(navigator.webkitGetUserMedia) !== 'undefined') { return true; } return false; },
  853. 3956628: ($0) => { if(typeof(Module['SDL2']) === 'undefined') { Module['SDL2'] = {}; } var SDL2 = Module['SDL2']; if (!$0) { SDL2.audio = {}; } else { SDL2.capture = {}; } if (!SDL2.audioContext) { if (typeof(AudioContext) !== 'undefined') { SDL2.audioContext = new AudioContext(); } else if (typeof(webkitAudioContext) !== 'undefined') { SDL2.audioContext = new webkitAudioContext(); } if (SDL2.audioContext) { if ((typeof navigator.userActivation) === 'undefined') { autoResumeAudioContext(SDL2.audioContext); } } } return SDL2.audioContext === undefined ? -1 : 0; },
  854. 3957180: () => { var SDL2 = Module['SDL2']; return SDL2.audioContext.sampleRate; },
  855. 3957248: ($0, $1, $2, $3) => { var SDL2 = Module['SDL2']; var have_microphone = function(stream) { if (SDL2.capture.silenceTimer !== undefined) { clearInterval(SDL2.capture.silenceTimer); SDL2.capture.silenceTimer = undefined; SDL2.capture.silenceBuffer = undefined } SDL2.capture.mediaStreamNode = SDL2.audioContext.createMediaStreamSource(stream); SDL2.capture.scriptProcessorNode = SDL2.audioContext.createScriptProcessor($1, $0, 1); SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) { if ((SDL2 === undefined) || (SDL2.capture === undefined)) { return; } audioProcessingEvent.outputBuffer.getChannelData(0).fill(0.0); SDL2.capture.currentCaptureBuffer = audioProcessingEvent.inputBuffer; dynCall('vi', $2, [$3]); }; SDL2.capture.mediaStreamNode.connect(SDL2.capture.scriptProcessorNode); SDL2.capture.scriptProcessorNode.connect(SDL2.audioContext.destination); SDL2.capture.stream = stream; }; var no_microphone = function(error) { }; SDL2.capture.silenceBuffer = SDL2.audioContext.createBuffer($0, $1, SDL2.audioContext.sampleRate); SDL2.capture.silenceBuffer.getChannelData(0).fill(0.0); var silence_callback = function() { SDL2.capture.currentCaptureBuffer = SDL2.capture.silenceBuffer; dynCall('vi', $2, [$3]); }; SDL2.capture.silenceTimer = setInterval(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1000); if ((navigator.mediaDevices !== undefined) && (navigator.mediaDevices.getUserMedia !== undefined)) { navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then(have_microphone).catch(no_microphone); } else if (navigator.webkitGetUserMedia !== undefined) { navigator.webkitGetUserMedia({ audio: true, video: false }, have_microphone, no_microphone); } },
  856. 3958941: ($0, $1, $2, $3) => { var SDL2 = Module['SDL2']; SDL2.audio.scriptProcessorNode = SDL2.audioContext['createScriptProcessor']($1, 0, $0); SDL2.audio.scriptProcessorNode['onaudioprocess'] = function (e) { if ((SDL2 === undefined) || (SDL2.audio === undefined)) { return; } if (SDL2.audio.silenceTimer !== undefined) { clearInterval(SDL2.audio.silenceTimer); SDL2.audio.silenceTimer = undefined; SDL2.audio.silenceBuffer = undefined; } SDL2.audio.currentOutputBuffer = e['outputBuffer']; dynCall('vi', $2, [$3]); }; SDL2.audio.scriptProcessorNode['connect'](SDL2.audioContext['destination']); if (SDL2.audioContext.state === 'suspended') { SDL2.audio.silenceBuffer = SDL2.audioContext.createBuffer($0, $1, SDL2.audioContext.sampleRate); SDL2.audio.silenceBuffer.getChannelData(0).fill(0.0); var silence_callback = function() { if ((typeof navigator.userActivation) !== 'undefined') { if (navigator.userActivation.hasBeenActive) { SDL2.audioContext.resume(); } } SDL2.audio.currentOutputBuffer = SDL2.audio.silenceBuffer; dynCall('vi', $2, [$3]); SDL2.audio.currentOutputBuffer = undefined; }; SDL2.audio.silenceTimer = setInterval(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1000); } },
  857. 3960116: ($0, $1) => { var SDL2 = Module['SDL2']; var numChannels = SDL2.capture.currentCaptureBuffer.numberOfChannels; for (var c = 0; c < numChannels; ++c) { var channelData = SDL2.capture.currentCaptureBuffer.getChannelData(c); if (channelData.length != $1) { throw 'Web Audio capture buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!'; } if (numChannels == 1) { for (var j = 0; j < $1; ++j) { setValue($0 + (j * 4), channelData[j], 'float'); } } else { for (var j = 0; j < $1; ++j) { setValue($0 + (((j * numChannels) + c) * 4), channelData[j], 'float'); } } } },
  858. 3960721: ($0, $1) => { var SDL2 = Module['SDL2']; var buf = $0 >>> 2; var numChannels = SDL2.audio.currentOutputBuffer['numberOfChannels']; for (var c = 0; c < numChannels; ++c) { var channelData = SDL2.audio.currentOutputBuffer['getChannelData'](c); if (channelData.length != $1) { throw 'Web Audio output buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!'; } for (var j = 0; j < $1; ++j) { channelData[j] = HEAPF32[buf + (j*numChannels + c)]; } } },
  859. 3961210: ($0) => { var SDL2 = Module['SDL2']; if ($0) { if (SDL2.capture.silenceTimer !== undefined) { clearInterval(SDL2.capture.silenceTimer); } if (SDL2.capture.stream !== undefined) { var tracks = SDL2.capture.stream.getAudioTracks(); for (var i = 0; i < tracks.length; i++) { SDL2.capture.stream.removeTrack(tracks[i]); } } if (SDL2.capture.scriptProcessorNode !== undefined) { SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) {}; SDL2.capture.scriptProcessorNode.disconnect(); } if (SDL2.capture.mediaStreamNode !== undefined) { SDL2.capture.mediaStreamNode.disconnect(); } SDL2.capture = undefined; } else { if (SDL2.audio.scriptProcessorNode != undefined) { SDL2.audio.scriptProcessorNode.disconnect(); } if (SDL2.audio.silenceTimer !== undefined) { clearInterval(SDL2.audio.silenceTimer); } SDL2.audio = undefined; } if ((SDL2.audioContext !== undefined) && (SDL2.audio === undefined) && (SDL2.capture === undefined)) { SDL2.audioContext.close(); SDL2.audioContext = undefined; } },
  860. 3962216: ($0, $1, $2) => { var w = $0; var h = $1; var pixels = $2; if (!Module['SDL2']) Module['SDL2'] = {}; var SDL2 = Module['SDL2']; if (SDL2.ctxCanvas !== Module['canvas']) { SDL2.ctx = Module['createContext'](Module['canvas'], false, true); SDL2.ctxCanvas = Module['canvas']; } if (SDL2.w !== w || SDL2.h !== h || SDL2.imageCtx !== SDL2.ctx) { SDL2.image = SDL2.ctx.createImageData(w, h); SDL2.w = w; SDL2.h = h; SDL2.imageCtx = SDL2.ctx; } var data = SDL2.image.data; var src = pixels / 4; var dst = 0; var num; if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) { num = data.length; while (dst < num) { var val = HEAP32[src]; data[dst ] = val & 0xff; data[dst+1] = (val >> 8) & 0xff; data[dst+2] = (val >> 16) & 0xff; data[dst+3] = 0xff; src++; dst += 4; } } else { if (SDL2.data32Data !== data) { SDL2.data32 = new Int32Array(data.buffer); SDL2.data8 = new Uint8Array(data.buffer); SDL2.data32Data = data; } var data32 = SDL2.data32; num = data32.length; data32.set(HEAP32.subarray(src, src + num)); var data8 = SDL2.data8; var i = 3; var j = i + 4*num; if (num % 8 == 0) { while (i < j) { data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; } } else { while (i < j) { data8[i] = 0xff; i = i + 4 | 0; } } } SDL2.ctx.putImageData(SDL2.image, 0, 0); },
  861. 3963684: ($0, $1, $2, $3, $4) => { var w = $0; var h = $1; var hot_x = $2; var hot_y = $3; var pixels = $4; var canvas = document.createElement("canvas"); canvas.width = w; canvas.height = h; var ctx = canvas.getContext("2d"); var image = ctx.createImageData(w, h); var data = image.data; var src = pixels / 4; var dst = 0; var num; if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) { num = data.length; while (dst < num) { var val = HEAP32[src]; data[dst ] = val & 0xff; data[dst+1] = (val >> 8) & 0xff; data[dst+2] = (val >> 16) & 0xff; data[dst+3] = (val >> 24) & 0xff; src++; dst += 4; } } else { var data32 = new Int32Array(data.buffer); num = data32.length; data32.set(HEAP32.subarray(src, src + num)); } ctx.putImageData(image, 0, 0); var url = hot_x === 0 && hot_y === 0 ? "url(" + canvas.toDataURL() + "), auto" : "url(" + canvas.toDataURL() + ") " + hot_x + " " + hot_y + ", auto"; var urlBuf = _malloc(url.length + 1); stringToUTF8(url, urlBuf, url.length + 1); return urlBuf; },
  862. 3964672: ($0) => { if (Module['canvas']) { Module['canvas'].style['cursor'] = UTF8ToString($0); } },
  863. 3964755: () => { if (Module['canvas']) { Module['canvas'].style['cursor'] = 'none'; } },
  864. 3964824: () => { return window.innerWidth; },
  865. 3964854: () => { return window.innerHeight; }
  866. };
  867. // end include: preamble.js
  868. class ExitStatus {
  869. name = 'ExitStatus';
  870. constructor(status) {
  871. this.message = `Program terminated with exit(${status})`;
  872. this.status = status;
  873. }
  874. }
  875. var callRuntimeCallbacks = (callbacks) => {
  876. while (callbacks.length > 0) {
  877. // Pass the module as the first argument.
  878. callbacks.shift()(Module);
  879. }
  880. };
  881. /**
  882. * @param {number} ptr
  883. * @param {string} type
  884. */
  885. function getValue(ptr, type = 'i8') {
  886. if (type.endsWith('*')) type = '*';
  887. switch (type) {
  888. case 'i1': return HEAP8[ptr];
  889. case 'i8': return HEAP8[ptr];
  890. case 'i16': return HEAP16[((ptr)>>1)];
  891. case 'i32': return HEAP32[((ptr)>>2)];
  892. case 'i64': return HEAP64[((ptr)>>3)];
  893. case 'float': return HEAPF32[((ptr)>>2)];
  894. case 'double': return HEAPF64[((ptr)>>3)];
  895. case '*': return HEAPU32[((ptr)>>2)];
  896. default: abort(`invalid type for getValue: ${type}`);
  897. }
  898. }
  899. var noExitRuntime = Module['noExitRuntime'] || false;
  900. var ptrToString = (ptr) => {
  901. assert(typeof ptr === 'number');
  902. // With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned.
  903. ptr >>>= 0;
  904. return '0x' + ptr.toString(16).padStart(8, '0');
  905. };
  906. /**
  907. * @param {number} ptr
  908. * @param {number} value
  909. * @param {string} type
  910. */
  911. function setValue(ptr, value, type = 'i8') {
  912. if (type.endsWith('*')) type = '*';
  913. switch (type) {
  914. case 'i1': HEAP8[ptr] = value; break;
  915. case 'i8': HEAP8[ptr] = value; break;
  916. case 'i16': HEAP16[((ptr)>>1)] = value; break;
  917. case 'i32': HEAP32[((ptr)>>2)] = value; break;
  918. case 'i64': HEAP64[((ptr)>>3)] = BigInt(value); break;
  919. case 'float': HEAPF32[((ptr)>>2)] = value; break;
  920. case 'double': HEAPF64[((ptr)>>3)] = value; break;
  921. case '*': HEAPU32[((ptr)>>2)] = value; break;
  922. default: abort(`invalid type for setValue: ${type}`);
  923. }
  924. }
  925. var stackRestore = (val) => __emscripten_stack_restore(val);
  926. var stackSave = () => _emscripten_stack_get_current();
  927. var warnOnce = (text) => {
  928. warnOnce.shown ||= {};
  929. if (!warnOnce.shown[text]) {
  930. warnOnce.shown[text] = 1;
  931. if (ENVIRONMENT_IS_NODE) text = 'warning: ' + text;
  932. err(text);
  933. }
  934. };
  935. /** @suppress {duplicate } */
  936. var syscallGetVarargI = () => {
  937. assert(SYSCALLS.varargs != undefined);
  938. // the `+` prepended here is necessary to convince the JSCompiler that varargs is indeed a number.
  939. var ret = HEAP32[((+SYSCALLS.varargs)>>2)];
  940. SYSCALLS.varargs += 4;
  941. return ret;
  942. };
  943. var syscallGetVarargP = syscallGetVarargI;
  944. var PATH = {
  945. isAbs:(path) => path.charAt(0) === '/',
  946. splitPath:(filename) => {
  947. var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
  948. return splitPathRe.exec(filename).slice(1);
  949. },
  950. normalizeArray:(parts, allowAboveRoot) => {
  951. // if the path tries to go above the root, `up` ends up > 0
  952. var up = 0;
  953. for (var i = parts.length - 1; i >= 0; i--) {
  954. var last = parts[i];
  955. if (last === '.') {
  956. parts.splice(i, 1);
  957. } else if (last === '..') {
  958. parts.splice(i, 1);
  959. up++;
  960. } else if (up) {
  961. parts.splice(i, 1);
  962. up--;
  963. }
  964. }
  965. // if the path is allowed to go above the root, restore leading ..s
  966. if (allowAboveRoot) {
  967. for (; up; up--) {
  968. parts.unshift('..');
  969. }
  970. }
  971. return parts;
  972. },
  973. normalize:(path) => {
  974. var isAbsolute = PATH.isAbs(path),
  975. trailingSlash = path.substr(-1) === '/';
  976. // Normalize the path
  977. path = PATH.normalizeArray(path.split('/').filter((p) => !!p), !isAbsolute).join('/');
  978. if (!path && !isAbsolute) {
  979. path = '.';
  980. }
  981. if (path && trailingSlash) {
  982. path += '/';
  983. }
  984. return (isAbsolute ? '/' : '') + path;
  985. },
  986. dirname:(path) => {
  987. var result = PATH.splitPath(path),
  988. root = result[0],
  989. dir = result[1];
  990. if (!root && !dir) {
  991. // No dirname whatsoever
  992. return '.';
  993. }
  994. if (dir) {
  995. // It has a dirname, strip trailing slash
  996. dir = dir.substr(0, dir.length - 1);
  997. }
  998. return root + dir;
  999. },
  1000. basename:(path) => {
  1001. // EMSCRIPTEN return '/'' for '/', not an empty string
  1002. if (path === '/') return '/';
  1003. path = PATH.normalize(path);
  1004. path = path.replace(/\/$/, "");
  1005. var lastSlash = path.lastIndexOf('/');
  1006. if (lastSlash === -1) return path;
  1007. return path.substr(lastSlash+1);
  1008. },
  1009. join:(...paths) => PATH.normalize(paths.join('/')),
  1010. join2:(l, r) => PATH.normalize(l + '/' + r),
  1011. };
  1012. var initRandomFill = () => {
  1013. if (typeof crypto == 'object' && typeof crypto['getRandomValues'] == 'function') {
  1014. // for modern web browsers
  1015. return (view) => crypto.getRandomValues(view);
  1016. } else
  1017. if (ENVIRONMENT_IS_NODE) {
  1018. // for nodejs with or without crypto support included
  1019. try {
  1020. var crypto_module = require('crypto');
  1021. var randomFillSync = crypto_module['randomFillSync'];
  1022. if (randomFillSync) {
  1023. // nodejs with LTS crypto support
  1024. return (view) => crypto_module['randomFillSync'](view);
  1025. }
  1026. // very old nodejs with the original crypto API
  1027. var randomBytes = crypto_module['randomBytes'];
  1028. return (view) => (
  1029. view.set(randomBytes(view.byteLength)),
  1030. // Return the original view to match modern native implementations.
  1031. view
  1032. );
  1033. } catch (e) {
  1034. // nodejs doesn't have crypto support
  1035. }
  1036. }
  1037. // we couldn't find a proper implementation, as Math.random() is not suitable for /dev/random, see emscripten-core/emscripten/pull/7096
  1038. abort('no cryptographic support found for randomDevice. consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: (array) => { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } };');
  1039. };
  1040. var randomFill = (view) => {
  1041. // Lazily init on the first invocation.
  1042. return (randomFill = initRandomFill())(view);
  1043. };
  1044. var PATH_FS = {
  1045. resolve:(...args) => {
  1046. var resolvedPath = '',
  1047. resolvedAbsolute = false;
  1048. for (var i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) {
  1049. var path = (i >= 0) ? args[i] : FS.cwd();
  1050. // Skip empty and invalid entries
  1051. if (typeof path != 'string') {
  1052. throw new TypeError('Arguments to path.resolve must be strings');
  1053. } else if (!path) {
  1054. return ''; // an invalid portion invalidates the whole thing
  1055. }
  1056. resolvedPath = path + '/' + resolvedPath;
  1057. resolvedAbsolute = PATH.isAbs(path);
  1058. }
  1059. // At this point the path should be resolved to a full absolute path, but
  1060. // handle relative paths to be safe (might happen when process.cwd() fails)
  1061. resolvedPath = PATH.normalizeArray(resolvedPath.split('/').filter((p) => !!p), !resolvedAbsolute).join('/');
  1062. return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
  1063. },
  1064. relative:(from, to) => {
  1065. from = PATH_FS.resolve(from).substr(1);
  1066. to = PATH_FS.resolve(to).substr(1);
  1067. function trim(arr) {
  1068. var start = 0;
  1069. for (; start < arr.length; start++) {
  1070. if (arr[start] !== '') break;
  1071. }
  1072. var end = arr.length - 1;
  1073. for (; end >= 0; end--) {
  1074. if (arr[end] !== '') break;
  1075. }
  1076. if (start > end) return [];
  1077. return arr.slice(start, end - start + 1);
  1078. }
  1079. var fromParts = trim(from.split('/'));
  1080. var toParts = trim(to.split('/'));
  1081. var length = Math.min(fromParts.length, toParts.length);
  1082. var samePartsLength = length;
  1083. for (var i = 0; i < length; i++) {
  1084. if (fromParts[i] !== toParts[i]) {
  1085. samePartsLength = i;
  1086. break;
  1087. }
  1088. }
  1089. var outputParts = [];
  1090. for (var i = samePartsLength; i < fromParts.length; i++) {
  1091. outputParts.push('..');
  1092. }
  1093. outputParts = outputParts.concat(toParts.slice(samePartsLength));
  1094. return outputParts.join('/');
  1095. },
  1096. };
  1097. var UTF8Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder() : undefined;
  1098. /**
  1099. * Given a pointer 'idx' to a null-terminated UTF8-encoded string in the given
  1100. * array that contains uint8 values, returns a copy of that string as a
  1101. * Javascript String object.
  1102. * heapOrArray is either a regular array, or a JavaScript typed array view.
  1103. * @param {number=} idx
  1104. * @param {number=} maxBytesToRead
  1105. * @return {string}
  1106. */
  1107. var UTF8ArrayToString = (heapOrArray, idx = 0, maxBytesToRead = NaN) => {
  1108. var endIdx = idx + maxBytesToRead;
  1109. var endPtr = idx;
  1110. // TextDecoder needs to know the byte length in advance, it doesn't stop on
  1111. // null terminator by itself. Also, use the length info to avoid running tiny
  1112. // strings through TextDecoder, since .subarray() allocates garbage.
  1113. // (As a tiny code save trick, compare endPtr against endIdx using a negation,
  1114. // so that undefined/NaN means Infinity)
  1115. while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr;
  1116. if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) {
  1117. return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr));
  1118. }
  1119. var str = '';
  1120. // If building with TextDecoder, we have already computed the string length
  1121. // above, so test loop end condition against that
  1122. while (idx < endPtr) {
  1123. // For UTF8 byte structure, see:
  1124. // http://en.wikipedia.org/wiki/UTF-8#Description
  1125. // https://www.ietf.org/rfc/rfc2279.txt
  1126. // https://tools.ietf.org/html/rfc3629
  1127. var u0 = heapOrArray[idx++];
  1128. if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; }
  1129. var u1 = heapOrArray[idx++] & 63;
  1130. if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; }
  1131. var u2 = heapOrArray[idx++] & 63;
  1132. if ((u0 & 0xF0) == 0xE0) {
  1133. u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
  1134. } else {
  1135. if ((u0 & 0xF8) != 0xF0) warnOnce('Invalid UTF-8 leading byte ' + ptrToString(u0) + ' encountered when deserializing a UTF-8 string in wasm memory to a JS string!');
  1136. u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heapOrArray[idx++] & 63);
  1137. }
  1138. if (u0 < 0x10000) {
  1139. str += String.fromCharCode(u0);
  1140. } else {
  1141. var ch = u0 - 0x10000;
  1142. str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
  1143. }
  1144. }
  1145. return str;
  1146. };
  1147. var FS_stdin_getChar_buffer = [];
  1148. var lengthBytesUTF8 = (str) => {
  1149. var len = 0;
  1150. for (var i = 0; i < str.length; ++i) {
  1151. // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code
  1152. // unit, not a Unicode code point of the character! So decode
  1153. // UTF16->UTF32->UTF8.
  1154. // See http://unicode.org/faq/utf_bom.html#utf16-3
  1155. var c = str.charCodeAt(i); // possibly a lead surrogate
  1156. if (c <= 0x7F) {
  1157. len++;
  1158. } else if (c <= 0x7FF) {
  1159. len += 2;
  1160. } else if (c >= 0xD800 && c <= 0xDFFF) {
  1161. len += 4; ++i;
  1162. } else {
  1163. len += 3;
  1164. }
  1165. }
  1166. return len;
  1167. };
  1168. var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
  1169. assert(typeof str === 'string', `stringToUTF8Array expects a string (got ${typeof str})`);
  1170. // Parameter maxBytesToWrite is not optional. Negative values, 0, null,
  1171. // undefined and false each don't write out any bytes.
  1172. if (!(maxBytesToWrite > 0))
  1173. return 0;
  1174. var startIdx = outIdx;
  1175. var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator.
  1176. for (var i = 0; i < str.length; ++i) {
  1177. // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code
  1178. // unit, not a Unicode code point of the character! So decode
  1179. // UTF16->UTF32->UTF8.
  1180. // See http://unicode.org/faq/utf_bom.html#utf16-3
  1181. // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description
  1182. // and https://www.ietf.org/rfc/rfc2279.txt
  1183. // and https://tools.ietf.org/html/rfc3629
  1184. var u = str.charCodeAt(i); // possibly a lead surrogate
  1185. if (u >= 0xD800 && u <= 0xDFFF) {
  1186. var u1 = str.charCodeAt(++i);
  1187. u = 0x10000 + ((u & 0x3FF) << 10) | (u1 & 0x3FF);
  1188. }
  1189. if (u <= 0x7F) {
  1190. if (outIdx >= endIdx) break;
  1191. heap[outIdx++] = u;
  1192. } else if (u <= 0x7FF) {
  1193. if (outIdx + 1 >= endIdx) break;
  1194. heap[outIdx++] = 0xC0 | (u >> 6);
  1195. heap[outIdx++] = 0x80 | (u & 63);
  1196. } else if (u <= 0xFFFF) {
  1197. if (outIdx + 2 >= endIdx) break;
  1198. heap[outIdx++] = 0xE0 | (u >> 12);
  1199. heap[outIdx++] = 0x80 | ((u >> 6) & 63);
  1200. heap[outIdx++] = 0x80 | (u & 63);
  1201. } else {
  1202. if (outIdx + 3 >= endIdx) break;
  1203. if (u > 0x10FFFF) warnOnce('Invalid Unicode code point ' + ptrToString(u) + ' encountered when serializing a JS string to a UTF-8 string in wasm memory! (Valid unicode code points should be in range 0-0x10FFFF).');
  1204. heap[outIdx++] = 0xF0 | (u >> 18);
  1205. heap[outIdx++] = 0x80 | ((u >> 12) & 63);
  1206. heap[outIdx++] = 0x80 | ((u >> 6) & 63);
  1207. heap[outIdx++] = 0x80 | (u & 63);
  1208. }
  1209. }
  1210. // Null-terminate the pointer to the buffer.
  1211. heap[outIdx] = 0;
  1212. return outIdx - startIdx;
  1213. };
  1214. /** @type {function(string, boolean=, number=)} */
  1215. function intArrayFromString(stringy, dontAddNull, length) {
  1216. var len = length > 0 ? length : lengthBytesUTF8(stringy)+1;
  1217. var u8array = new Array(len);
  1218. var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length);
  1219. if (dontAddNull) u8array.length = numBytesWritten;
  1220. return u8array;
  1221. }
  1222. var FS_stdin_getChar = () => {
  1223. if (!FS_stdin_getChar_buffer.length) {
  1224. var result = null;
  1225. if (ENVIRONMENT_IS_NODE) {
  1226. // we will read data by chunks of BUFSIZE
  1227. var BUFSIZE = 256;
  1228. var buf = Buffer.alloc(BUFSIZE);
  1229. var bytesRead = 0;
  1230. // For some reason we must suppress a closure warning here, even though
  1231. // fd definitely exists on process.stdin, and is even the proper way to
  1232. // get the fd of stdin,
  1233. // https://github.com/nodejs/help/issues/2136#issuecomment-523649904
  1234. // This started to happen after moving this logic out of library_tty.js,
  1235. // so it is related to the surrounding code in some unclear manner.
  1236. /** @suppress {missingProperties} */
  1237. var fd = process.stdin.fd;
  1238. try {
  1239. bytesRead = fs.readSync(fd, buf, 0, BUFSIZE);
  1240. } catch(e) {
  1241. // Cross-platform differences: on Windows, reading EOF throws an
  1242. // exception, but on other OSes, reading EOF returns 0. Uniformize
  1243. // behavior by treating the EOF exception to return 0.
  1244. if (e.toString().includes('EOF')) bytesRead = 0;
  1245. else throw e;
  1246. }
  1247. if (bytesRead > 0) {
  1248. result = buf.slice(0, bytesRead).toString('utf-8');
  1249. }
  1250. } else
  1251. if (typeof window != 'undefined' &&
  1252. typeof window.prompt == 'function') {
  1253. // Browser.
  1254. result = window.prompt('Input: '); // returns null on cancel
  1255. if (result !== null) {
  1256. result += '\n';
  1257. }
  1258. } else
  1259. {}
  1260. if (!result) {
  1261. return null;
  1262. }
  1263. FS_stdin_getChar_buffer = intArrayFromString(result, true);
  1264. }
  1265. return FS_stdin_getChar_buffer.shift();
  1266. };
  1267. var TTY = {
  1268. ttys:[],
  1269. init() {
  1270. // https://github.com/emscripten-core/emscripten/pull/1555
  1271. // if (ENVIRONMENT_IS_NODE) {
  1272. // // currently, FS.init does not distinguish if process.stdin is a file or TTY
  1273. // // device, it always assumes it's a TTY device. because of this, we're forcing
  1274. // // process.stdin to UTF8 encoding to at least make stdin reading compatible
  1275. // // with text files until FS.init can be refactored.
  1276. // process.stdin.setEncoding('utf8');
  1277. // }
  1278. },
  1279. shutdown() {
  1280. // https://github.com/emscripten-core/emscripten/pull/1555
  1281. // if (ENVIRONMENT_IS_NODE) {
  1282. // // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)?
  1283. // // isaacs: because now it's reading from the stream, you've expressed interest in it, so that read() kicks off a _read() which creates a ReadReq operation
  1284. // // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists?
  1285. // // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle
  1286. // // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call
  1287. // process.stdin.pause();
  1288. // }
  1289. },
  1290. register(dev, ops) {
  1291. TTY.ttys[dev] = { input: [], output: [], ops: ops };
  1292. FS.registerDevice(dev, TTY.stream_ops);
  1293. },
  1294. stream_ops:{
  1295. open(stream) {
  1296. var tty = TTY.ttys[stream.node.rdev];
  1297. if (!tty) {
  1298. throw new FS.ErrnoError(43);
  1299. }
  1300. stream.tty = tty;
  1301. stream.seekable = false;
  1302. },
  1303. close(stream) {
  1304. // flush any pending line data
  1305. stream.tty.ops.fsync(stream.tty);
  1306. },
  1307. fsync(stream) {
  1308. stream.tty.ops.fsync(stream.tty);
  1309. },
  1310. read(stream, buffer, offset, length, pos /* ignored */) {
  1311. if (!stream.tty || !stream.tty.ops.get_char) {
  1312. throw new FS.ErrnoError(60);
  1313. }
  1314. var bytesRead = 0;
  1315. for (var i = 0; i < length; i++) {
  1316. var result;
  1317. try {
  1318. result = stream.tty.ops.get_char(stream.tty);
  1319. } catch (e) {
  1320. throw new FS.ErrnoError(29);
  1321. }
  1322. if (result === undefined && bytesRead === 0) {
  1323. throw new FS.ErrnoError(6);
  1324. }
  1325. if (result === null || result === undefined) break;
  1326. bytesRead++;
  1327. buffer[offset+i] = result;
  1328. }
  1329. if (bytesRead) {
  1330. stream.node.timestamp = Date.now();
  1331. }
  1332. return bytesRead;
  1333. },
  1334. write(stream, buffer, offset, length, pos) {
  1335. if (!stream.tty || !stream.tty.ops.put_char) {
  1336. throw new FS.ErrnoError(60);
  1337. }
  1338. try {
  1339. for (var i = 0; i < length; i++) {
  1340. stream.tty.ops.put_char(stream.tty, buffer[offset+i]);
  1341. }
  1342. } catch (e) {
  1343. throw new FS.ErrnoError(29);
  1344. }
  1345. if (length) {
  1346. stream.node.timestamp = Date.now();
  1347. }
  1348. return i;
  1349. },
  1350. },
  1351. default_tty_ops:{
  1352. get_char(tty) {
  1353. return FS_stdin_getChar();
  1354. },
  1355. put_char(tty, val) {
  1356. if (val === null || val === 10) {
  1357. out(UTF8ArrayToString(tty.output));
  1358. tty.output = [];
  1359. } else {
  1360. if (val != 0) tty.output.push(val); // val == 0 would cut text output off in the middle.
  1361. }
  1362. },
  1363. fsync(tty) {
  1364. if (tty.output && tty.output.length > 0) {
  1365. out(UTF8ArrayToString(tty.output));
  1366. tty.output = [];
  1367. }
  1368. },
  1369. ioctl_tcgets(tty) {
  1370. // typical setting
  1371. return {
  1372. c_iflag: 25856,
  1373. c_oflag: 5,
  1374. c_cflag: 191,
  1375. c_lflag: 35387,
  1376. c_cc: [
  1377. 0x03, 0x1c, 0x7f, 0x15, 0x04, 0x00, 0x01, 0x00, 0x11, 0x13, 0x1a, 0x00,
  1378. 0x12, 0x0f, 0x17, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1379. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1380. ]
  1381. };
  1382. },
  1383. ioctl_tcsets(tty, optional_actions, data) {
  1384. // currently just ignore
  1385. return 0;
  1386. },
  1387. ioctl_tiocgwinsz(tty) {
  1388. return [24, 80];
  1389. },
  1390. },
  1391. default_tty1_ops:{
  1392. put_char(tty, val) {
  1393. if (val === null || val === 10) {
  1394. err(UTF8ArrayToString(tty.output));
  1395. tty.output = [];
  1396. } else {
  1397. if (val != 0) tty.output.push(val);
  1398. }
  1399. },
  1400. fsync(tty) {
  1401. if (tty.output && tty.output.length > 0) {
  1402. err(UTF8ArrayToString(tty.output));
  1403. tty.output = [];
  1404. }
  1405. },
  1406. },
  1407. };
  1408. var zeroMemory = (address, size) => {
  1409. HEAPU8.fill(0, address, address + size);
  1410. };
  1411. var alignMemory = (size, alignment) => {
  1412. assert(alignment, "alignment argument is required");
  1413. return Math.ceil(size / alignment) * alignment;
  1414. };
  1415. var mmapAlloc = (size) => {
  1416. abort('internal error: mmapAlloc called but `emscripten_builtin_memalign` native symbol not exported');
  1417. };
  1418. var MEMFS = {
  1419. ops_table:null,
  1420. mount(mount) {
  1421. return MEMFS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
  1422. },
  1423. createNode(parent, name, mode, dev) {
  1424. if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
  1425. // no supported
  1426. throw new FS.ErrnoError(63);
  1427. }
  1428. MEMFS.ops_table ||= {
  1429. dir: {
  1430. node: {
  1431. getattr: MEMFS.node_ops.getattr,
  1432. setattr: MEMFS.node_ops.setattr,
  1433. lookup: MEMFS.node_ops.lookup,
  1434. mknod: MEMFS.node_ops.mknod,
  1435. rename: MEMFS.node_ops.rename,
  1436. unlink: MEMFS.node_ops.unlink,
  1437. rmdir: MEMFS.node_ops.rmdir,
  1438. readdir: MEMFS.node_ops.readdir,
  1439. symlink: MEMFS.node_ops.symlink
  1440. },
  1441. stream: {
  1442. llseek: MEMFS.stream_ops.llseek
  1443. }
  1444. },
  1445. file: {
  1446. node: {
  1447. getattr: MEMFS.node_ops.getattr,
  1448. setattr: MEMFS.node_ops.setattr
  1449. },
  1450. stream: {
  1451. llseek: MEMFS.stream_ops.llseek,
  1452. read: MEMFS.stream_ops.read,
  1453. write: MEMFS.stream_ops.write,
  1454. allocate: MEMFS.stream_ops.allocate,
  1455. mmap: MEMFS.stream_ops.mmap,
  1456. msync: MEMFS.stream_ops.msync
  1457. }
  1458. },
  1459. link: {
  1460. node: {
  1461. getattr: MEMFS.node_ops.getattr,
  1462. setattr: MEMFS.node_ops.setattr,
  1463. readlink: MEMFS.node_ops.readlink
  1464. },
  1465. stream: {}
  1466. },
  1467. chrdev: {
  1468. node: {
  1469. getattr: MEMFS.node_ops.getattr,
  1470. setattr: MEMFS.node_ops.setattr
  1471. },
  1472. stream: FS.chrdev_stream_ops
  1473. }
  1474. };
  1475. var node = FS.createNode(parent, name, mode, dev);
  1476. if (FS.isDir(node.mode)) {
  1477. node.node_ops = MEMFS.ops_table.dir.node;
  1478. node.stream_ops = MEMFS.ops_table.dir.stream;
  1479. node.contents = {};
  1480. } else if (FS.isFile(node.mode)) {
  1481. node.node_ops = MEMFS.ops_table.file.node;
  1482. node.stream_ops = MEMFS.ops_table.file.stream;
  1483. node.usedBytes = 0; // The actual number of bytes used in the typed array, as opposed to contents.length which gives the whole capacity.
  1484. // When the byte data of the file is populated, this will point to either a typed array, or a normal JS array. Typed arrays are preferred
  1485. // for performance, and used by default. However, typed arrays are not resizable like normal JS arrays are, so there is a small disk size
  1486. // penalty involved for appending file writes that continuously grow a file similar to std::vector capacity vs used -scheme.
  1487. node.contents = null;
  1488. } else if (FS.isLink(node.mode)) {
  1489. node.node_ops = MEMFS.ops_table.link.node;
  1490. node.stream_ops = MEMFS.ops_table.link.stream;
  1491. } else if (FS.isChrdev(node.mode)) {
  1492. node.node_ops = MEMFS.ops_table.chrdev.node;
  1493. node.stream_ops = MEMFS.ops_table.chrdev.stream;
  1494. }
  1495. node.timestamp = Date.now();
  1496. // add the new node to the parent
  1497. if (parent) {
  1498. parent.contents[name] = node;
  1499. parent.timestamp = node.timestamp;
  1500. }
  1501. return node;
  1502. },
  1503. getFileDataAsTypedArray(node) {
  1504. if (!node.contents) return new Uint8Array(0);
  1505. if (node.contents.subarray) return node.contents.subarray(0, node.usedBytes); // Make sure to not return excess unused bytes.
  1506. return new Uint8Array(node.contents);
  1507. },
  1508. expandFileStorage(node, newCapacity) {
  1509. var prevCapacity = node.contents ? node.contents.length : 0;
  1510. if (prevCapacity >= newCapacity) return; // No need to expand, the storage was already large enough.
  1511. // Don't expand strictly to the given requested limit if it's only a very small increase, but instead geometrically grow capacity.
  1512. // For small filesizes (<1MB), perform size*2 geometric increase, but for large sizes, do a much more conservative size*1.125 increase to
  1513. // avoid overshooting the allocation cap by a very large margin.
  1514. var CAPACITY_DOUBLING_MAX = 1024 * 1024;
  1515. newCapacity = Math.max(newCapacity, (prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2.0 : 1.125)) >>> 0);
  1516. if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); // At minimum allocate 256b for each file when expanding.
  1517. var oldContents = node.contents;
  1518. node.contents = new Uint8Array(newCapacity); // Allocate new storage.
  1519. if (node.usedBytes > 0) node.contents.set(oldContents.subarray(0, node.usedBytes), 0); // Copy old data over to the new storage.
  1520. },
  1521. resizeFileStorage(node, newSize) {
  1522. if (node.usedBytes == newSize) return;
  1523. if (newSize == 0) {
  1524. node.contents = null; // Fully decommit when requesting a resize to zero.
  1525. node.usedBytes = 0;
  1526. } else {
  1527. var oldContents = node.contents;
  1528. node.contents = new Uint8Array(newSize); // Allocate new storage.
  1529. if (oldContents) {
  1530. node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))); // Copy old data over to the new storage.
  1531. }
  1532. node.usedBytes = newSize;
  1533. }
  1534. },
  1535. node_ops:{
  1536. getattr(node) {
  1537. var attr = {};
  1538. // device numbers reuse inode numbers.
  1539. attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
  1540. attr.ino = node.id;
  1541. attr.mode = node.mode;
  1542. attr.nlink = 1;
  1543. attr.uid = 0;
  1544. attr.gid = 0;
  1545. attr.rdev = node.rdev;
  1546. if (FS.isDir(node.mode)) {
  1547. attr.size = 4096;
  1548. } else if (FS.isFile(node.mode)) {
  1549. attr.size = node.usedBytes;
  1550. } else if (FS.isLink(node.mode)) {
  1551. attr.size = node.link.length;
  1552. } else {
  1553. attr.size = 0;
  1554. }
  1555. attr.atime = new Date(node.timestamp);
  1556. attr.mtime = new Date(node.timestamp);
  1557. attr.ctime = new Date(node.timestamp);
  1558. // NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize),
  1559. // but this is not required by the standard.
  1560. attr.blksize = 4096;
  1561. attr.blocks = Math.ceil(attr.size / attr.blksize);
  1562. return attr;
  1563. },
  1564. setattr(node, attr) {
  1565. if (attr.mode !== undefined) {
  1566. node.mode = attr.mode;
  1567. }
  1568. if (attr.timestamp !== undefined) {
  1569. node.timestamp = attr.timestamp;
  1570. }
  1571. if (attr.size !== undefined) {
  1572. MEMFS.resizeFileStorage(node, attr.size);
  1573. }
  1574. },
  1575. lookup(parent, name) {
  1576. throw new FS.ErrnoError(44);
  1577. },
  1578. mknod(parent, name, mode, dev) {
  1579. return MEMFS.createNode(parent, name, mode, dev);
  1580. },
  1581. rename(old_node, new_dir, new_name) {
  1582. // if we're overwriting a directory at new_name, make sure it's empty.
  1583. if (FS.isDir(old_node.mode)) {
  1584. var new_node;
  1585. try {
  1586. new_node = FS.lookupNode(new_dir, new_name);
  1587. } catch (e) {
  1588. }
  1589. if (new_node) {
  1590. for (var i in new_node.contents) {
  1591. throw new FS.ErrnoError(55);
  1592. }
  1593. }
  1594. }
  1595. // do the internal rewiring
  1596. delete old_node.parent.contents[old_node.name];
  1597. old_node.parent.timestamp = Date.now()
  1598. old_node.name = new_name;
  1599. new_dir.contents[new_name] = old_node;
  1600. new_dir.timestamp = old_node.parent.timestamp;
  1601. },
  1602. unlink(parent, name) {
  1603. delete parent.contents[name];
  1604. parent.timestamp = Date.now();
  1605. },
  1606. rmdir(parent, name) {
  1607. var node = FS.lookupNode(parent, name);
  1608. for (var i in node.contents) {
  1609. throw new FS.ErrnoError(55);
  1610. }
  1611. delete parent.contents[name];
  1612. parent.timestamp = Date.now();
  1613. },
  1614. readdir(node) {
  1615. var entries = ['.', '..'];
  1616. for (var key of Object.keys(node.contents)) {
  1617. entries.push(key);
  1618. }
  1619. return entries;
  1620. },
  1621. symlink(parent, newname, oldpath) {
  1622. var node = MEMFS.createNode(parent, newname, 511 /* 0777 */ | 40960, 0);
  1623. node.link = oldpath;
  1624. return node;
  1625. },
  1626. readlink(node) {
  1627. if (!FS.isLink(node.mode)) {
  1628. throw new FS.ErrnoError(28);
  1629. }
  1630. return node.link;
  1631. },
  1632. },
  1633. stream_ops:{
  1634. read(stream, buffer, offset, length, position) {
  1635. var contents = stream.node.contents;
  1636. if (position >= stream.node.usedBytes) return 0;
  1637. var size = Math.min(stream.node.usedBytes - position, length);
  1638. assert(size >= 0);
  1639. if (size > 8 && contents.subarray) { // non-trivial, and typed array
  1640. buffer.set(contents.subarray(position, position + size), offset);
  1641. } else {
  1642. for (var i = 0; i < size; i++) buffer[offset + i] = contents[position + i];
  1643. }
  1644. return size;
  1645. },
  1646. write(stream, buffer, offset, length, position, canOwn) {
  1647. // The data buffer should be a typed array view
  1648. assert(!(buffer instanceof ArrayBuffer));
  1649. // If the buffer is located in main memory (HEAP), and if
  1650. // memory can grow, we can't hold on to references of the
  1651. // memory buffer, as they may get invalidated. That means we
  1652. // need to do copy its contents.
  1653. if (buffer.buffer === HEAP8.buffer) {
  1654. canOwn = false;
  1655. }
  1656. if (!length) return 0;
  1657. var node = stream.node;
  1658. node.timestamp = Date.now();
  1659. if (buffer.subarray && (!node.contents || node.contents.subarray)) { // This write is from a typed array to a typed array?
  1660. if (canOwn) {
  1661. assert(position === 0, 'canOwn must imply no weird position inside the file');
  1662. node.contents = buffer.subarray(offset, offset + length);
  1663. node.usedBytes = length;
  1664. return length;
  1665. } else if (node.usedBytes === 0 && position === 0) { // If this is a simple first write to an empty file, do a fast set since we don't need to care about old data.
  1666. node.contents = buffer.slice(offset, offset + length);
  1667. node.usedBytes = length;
  1668. return length;
  1669. } else if (position + length <= node.usedBytes) { // Writing to an already allocated and used subrange of the file?
  1670. node.contents.set(buffer.subarray(offset, offset + length), position);
  1671. return length;
  1672. }
  1673. }
  1674. // Appending to an existing file and we need to reallocate, or source data did not come as a typed array.
  1675. MEMFS.expandFileStorage(node, position+length);
  1676. if (node.contents.subarray && buffer.subarray) {
  1677. // Use typed array write which is available.
  1678. node.contents.set(buffer.subarray(offset, offset + length), position);
  1679. } else {
  1680. for (var i = 0; i < length; i++) {
  1681. node.contents[position + i] = buffer[offset + i]; // Or fall back to manual write if not.
  1682. }
  1683. }
  1684. node.usedBytes = Math.max(node.usedBytes, position + length);
  1685. return length;
  1686. },
  1687. llseek(stream, offset, whence) {
  1688. var position = offset;
  1689. if (whence === 1) {
  1690. position += stream.position;
  1691. } else if (whence === 2) {
  1692. if (FS.isFile(stream.node.mode)) {
  1693. position += stream.node.usedBytes;
  1694. }
  1695. }
  1696. if (position < 0) {
  1697. throw new FS.ErrnoError(28);
  1698. }
  1699. return position;
  1700. },
  1701. allocate(stream, offset, length) {
  1702. MEMFS.expandFileStorage(stream.node, offset + length);
  1703. stream.node.usedBytes = Math.max(stream.node.usedBytes, offset + length);
  1704. },
  1705. mmap(stream, length, position, prot, flags) {
  1706. if (!FS.isFile(stream.node.mode)) {
  1707. throw new FS.ErrnoError(43);
  1708. }
  1709. var ptr;
  1710. var allocated;
  1711. var contents = stream.node.contents;
  1712. // Only make a new copy when MAP_PRIVATE is specified.
  1713. if (!(flags & 2) && contents && contents.buffer === HEAP8.buffer) {
  1714. // We can't emulate MAP_SHARED when the file is not backed by the
  1715. // buffer we're mapping to (e.g. the HEAP buffer).
  1716. allocated = false;
  1717. ptr = contents.byteOffset;
  1718. } else {
  1719. allocated = true;
  1720. ptr = mmapAlloc(length);
  1721. if (!ptr) {
  1722. throw new FS.ErrnoError(48);
  1723. }
  1724. if (contents) {
  1725. // Try to avoid unnecessary slices.
  1726. if (position > 0 || position + length < contents.length) {
  1727. if (contents.subarray) {
  1728. contents = contents.subarray(position, position + length);
  1729. } else {
  1730. contents = Array.prototype.slice.call(contents, position, position + length);
  1731. }
  1732. }
  1733. HEAP8.set(contents, ptr);
  1734. }
  1735. }
  1736. return { ptr, allocated };
  1737. },
  1738. msync(stream, buffer, offset, length, mmapFlags) {
  1739. MEMFS.stream_ops.write(stream, buffer, 0, length, offset, false);
  1740. // should we check if bytesWritten and length are the same?
  1741. return 0;
  1742. },
  1743. },
  1744. };
  1745. /** @param {boolean=} noRunDep */
  1746. var asyncLoad = (url, onload, onerror, noRunDep) => {
  1747. var dep = !noRunDep ? getUniqueRunDependency(`al ${url}`) : '';
  1748. readAsync(url).then(
  1749. (arrayBuffer) => {
  1750. assert(arrayBuffer, `Loading data file "${url}" failed (no arrayBuffer).`);
  1751. onload(new Uint8Array(arrayBuffer));
  1752. if (dep) removeRunDependency(dep);
  1753. },
  1754. (err) => {
  1755. if (onerror) {
  1756. onerror();
  1757. } else {
  1758. throw `Loading data file "${url}" failed.`;
  1759. }
  1760. }
  1761. );
  1762. if (dep) addRunDependency(dep);
  1763. };
  1764. var FS_createDataFile = (parent, name, fileData, canRead, canWrite, canOwn) => {
  1765. FS.createDataFile(parent, name, fileData, canRead, canWrite, canOwn);
  1766. };
  1767. var preloadPlugins = Module['preloadPlugins'] || [];
  1768. var FS_handledByPreloadPlugin = (byteArray, fullname, finish, onerror) => {
  1769. // Ensure plugins are ready.
  1770. if (typeof Browser != 'undefined') Browser.init();
  1771. var handled = false;
  1772. preloadPlugins.forEach((plugin) => {
  1773. if (handled) return;
  1774. if (plugin['canHandle'](fullname)) {
  1775. plugin['handle'](byteArray, fullname, finish, onerror);
  1776. handled = true;
  1777. }
  1778. });
  1779. return handled;
  1780. };
  1781. var FS_createPreloadedFile = (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) => {
  1782. // TODO we should allow people to just pass in a complete filename instead
  1783. // of parent and name being that we just join them anyways
  1784. var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent;
  1785. var dep = getUniqueRunDependency(`cp ${fullname}`); // might have several active requests for the same fullname
  1786. function processData(byteArray) {
  1787. function finish(byteArray) {
  1788. preFinish?.();
  1789. if (!dontCreateFile) {
  1790. FS_createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
  1791. }
  1792. onload?.();
  1793. removeRunDependency(dep);
  1794. }
  1795. if (FS_handledByPreloadPlugin(byteArray, fullname, finish, () => {
  1796. onerror?.();
  1797. removeRunDependency(dep);
  1798. })) {
  1799. return;
  1800. }
  1801. finish(byteArray);
  1802. }
  1803. addRunDependency(dep);
  1804. if (typeof url == 'string') {
  1805. asyncLoad(url, processData, onerror);
  1806. } else {
  1807. processData(url);
  1808. }
  1809. };
  1810. var FS_modeStringToFlags = (str) => {
  1811. var flagModes = {
  1812. 'r': 0,
  1813. 'r+': 2,
  1814. 'w': 512 | 64 | 1,
  1815. 'w+': 512 | 64 | 2,
  1816. 'a': 1024 | 64 | 1,
  1817. 'a+': 1024 | 64 | 2,
  1818. };
  1819. var flags = flagModes[str];
  1820. if (typeof flags == 'undefined') {
  1821. throw new Error(`Unknown file open mode: ${str}`);
  1822. }
  1823. return flags;
  1824. };
  1825. var FS_getMode = (canRead, canWrite) => {
  1826. var mode = 0;
  1827. if (canRead) mode |= 292 | 73;
  1828. if (canWrite) mode |= 146;
  1829. return mode;
  1830. };
  1831. /**
  1832. * Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the
  1833. * emscripten HEAP, returns a copy of that string as a Javascript String object.
  1834. *
  1835. * @param {number} ptr
  1836. * @param {number=} maxBytesToRead - An optional length that specifies the
  1837. * maximum number of bytes to read. You can omit this parameter to scan the
  1838. * string until the first 0 byte. If maxBytesToRead is passed, and the string
  1839. * at [ptr, ptr+maxBytesToReadr[ contains a null byte in the middle, then the
  1840. * string will cut short at that byte index (i.e. maxBytesToRead will not
  1841. * produce a string of exact length [ptr, ptr+maxBytesToRead[) N.B. mixing
  1842. * frequent uses of UTF8ToString() with and without maxBytesToRead may throw
  1843. * JS JIT optimizations off, so it is worth to consider consistently using one
  1844. * @return {string}
  1845. */
  1846. var UTF8ToString = (ptr, maxBytesToRead) => {
  1847. assert(typeof ptr == 'number', `UTF8ToString expects a number (got ${typeof ptr})`);
  1848. return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : '';
  1849. };
  1850. var strError = (errno) => {
  1851. return UTF8ToString(_strerror(errno));
  1852. };
  1853. var ERRNO_CODES = {
  1854. 'EPERM': 63,
  1855. 'ENOENT': 44,
  1856. 'ESRCH': 71,
  1857. 'EINTR': 27,
  1858. 'EIO': 29,
  1859. 'ENXIO': 60,
  1860. 'E2BIG': 1,
  1861. 'ENOEXEC': 45,
  1862. 'EBADF': 8,
  1863. 'ECHILD': 12,
  1864. 'EAGAIN': 6,
  1865. 'EWOULDBLOCK': 6,
  1866. 'ENOMEM': 48,
  1867. 'EACCES': 2,
  1868. 'EFAULT': 21,
  1869. 'ENOTBLK': 105,
  1870. 'EBUSY': 10,
  1871. 'EEXIST': 20,
  1872. 'EXDEV': 75,
  1873. 'ENODEV': 43,
  1874. 'ENOTDIR': 54,
  1875. 'EISDIR': 31,
  1876. 'EINVAL': 28,
  1877. 'ENFILE': 41,
  1878. 'EMFILE': 33,
  1879. 'ENOTTY': 59,
  1880. 'ETXTBSY': 74,
  1881. 'EFBIG': 22,
  1882. 'ENOSPC': 51,
  1883. 'ESPIPE': 70,
  1884. 'EROFS': 69,
  1885. 'EMLINK': 34,
  1886. 'EPIPE': 64,
  1887. 'EDOM': 18,
  1888. 'ERANGE': 68,
  1889. 'ENOMSG': 49,
  1890. 'EIDRM': 24,
  1891. 'ECHRNG': 106,
  1892. 'EL2NSYNC': 156,
  1893. 'EL3HLT': 107,
  1894. 'EL3RST': 108,
  1895. 'ELNRNG': 109,
  1896. 'EUNATCH': 110,
  1897. 'ENOCSI': 111,
  1898. 'EL2HLT': 112,
  1899. 'EDEADLK': 16,
  1900. 'ENOLCK': 46,
  1901. 'EBADE': 113,
  1902. 'EBADR': 114,
  1903. 'EXFULL': 115,
  1904. 'ENOANO': 104,
  1905. 'EBADRQC': 103,
  1906. 'EBADSLT': 102,
  1907. 'EDEADLOCK': 16,
  1908. 'EBFONT': 101,
  1909. 'ENOSTR': 100,
  1910. 'ENODATA': 116,
  1911. 'ETIME': 117,
  1912. 'ENOSR': 118,
  1913. 'ENONET': 119,
  1914. 'ENOPKG': 120,
  1915. 'EREMOTE': 121,
  1916. 'ENOLINK': 47,
  1917. 'EADV': 122,
  1918. 'ESRMNT': 123,
  1919. 'ECOMM': 124,
  1920. 'EPROTO': 65,
  1921. 'EMULTIHOP': 36,
  1922. 'EDOTDOT': 125,
  1923. 'EBADMSG': 9,
  1924. 'ENOTUNIQ': 126,
  1925. 'EBADFD': 127,
  1926. 'EREMCHG': 128,
  1927. 'ELIBACC': 129,
  1928. 'ELIBBAD': 130,
  1929. 'ELIBSCN': 131,
  1930. 'ELIBMAX': 132,
  1931. 'ELIBEXEC': 133,
  1932. 'ENOSYS': 52,
  1933. 'ENOTEMPTY': 55,
  1934. 'ENAMETOOLONG': 37,
  1935. 'ELOOP': 32,
  1936. 'EOPNOTSUPP': 138,
  1937. 'EPFNOSUPPORT': 139,
  1938. 'ECONNRESET': 15,
  1939. 'ENOBUFS': 42,
  1940. 'EAFNOSUPPORT': 5,
  1941. 'EPROTOTYPE': 67,
  1942. 'ENOTSOCK': 57,
  1943. 'ENOPROTOOPT': 50,
  1944. 'ESHUTDOWN': 140,
  1945. 'ECONNREFUSED': 14,
  1946. 'EADDRINUSE': 3,
  1947. 'ECONNABORTED': 13,
  1948. 'ENETUNREACH': 40,
  1949. 'ENETDOWN': 38,
  1950. 'ETIMEDOUT': 73,
  1951. 'EHOSTDOWN': 142,
  1952. 'EHOSTUNREACH': 23,
  1953. 'EINPROGRESS': 26,
  1954. 'EALREADY': 7,
  1955. 'EDESTADDRREQ': 17,
  1956. 'EMSGSIZE': 35,
  1957. 'EPROTONOSUPPORT': 66,
  1958. 'ESOCKTNOSUPPORT': 137,
  1959. 'EADDRNOTAVAIL': 4,
  1960. 'ENETRESET': 39,
  1961. 'EISCONN': 30,
  1962. 'ENOTCONN': 53,
  1963. 'ETOOMANYREFS': 141,
  1964. 'EUSERS': 136,
  1965. 'EDQUOT': 19,
  1966. 'ESTALE': 72,
  1967. 'ENOTSUP': 138,
  1968. 'ENOMEDIUM': 148,
  1969. 'EILSEQ': 25,
  1970. 'EOVERFLOW': 61,
  1971. 'ECANCELED': 11,
  1972. 'ENOTRECOVERABLE': 56,
  1973. 'EOWNERDEAD': 62,
  1974. 'ESTRPIPE': 135,
  1975. };
  1976. var FS = {
  1977. root:null,
  1978. mounts:[],
  1979. devices:{
  1980. },
  1981. streams:[],
  1982. nextInode:1,
  1983. nameTable:null,
  1984. currentPath:"/",
  1985. initialized:false,
  1986. ignorePermissions:true,
  1987. ErrnoError:class extends Error {
  1988. name = 'ErrnoError';
  1989. // We set the `name` property to be able to identify `FS.ErrnoError`
  1990. // - the `name` is a standard ECMA-262 property of error objects. Kind of good to have it anyway.
  1991. // - when using PROXYFS, an error can come from an underlying FS
  1992. // as different FS objects have their own FS.ErrnoError each,
  1993. // the test `err instanceof FS.ErrnoError` won't detect an error coming from another filesystem, causing bugs.
  1994. // we'll use the reliable test `err.name == "ErrnoError"` instead
  1995. constructor(errno) {
  1996. super(runtimeInitialized ? strError(errno) : '');
  1997. this.errno = errno;
  1998. for (var key in ERRNO_CODES) {
  1999. if (ERRNO_CODES[key] === errno) {
  2000. this.code = key;
  2001. break;
  2002. }
  2003. }
  2004. }
  2005. },
  2006. filesystems:null,
  2007. syncFSRequests:0,
  2008. readFiles:{
  2009. },
  2010. FSStream:class {
  2011. shared = {};
  2012. get object() {
  2013. return this.node;
  2014. }
  2015. set object(val) {
  2016. this.node = val;
  2017. }
  2018. get isRead() {
  2019. return (this.flags & 2097155) !== 1;
  2020. }
  2021. get isWrite() {
  2022. return (this.flags & 2097155) !== 0;
  2023. }
  2024. get isAppend() {
  2025. return (this.flags & 1024);
  2026. }
  2027. get flags() {
  2028. return this.shared.flags;
  2029. }
  2030. set flags(val) {
  2031. this.shared.flags = val;
  2032. }
  2033. get position() {
  2034. return this.shared.position;
  2035. }
  2036. set position(val) {
  2037. this.shared.position = val;
  2038. }
  2039. },
  2040. FSNode:class {
  2041. node_ops = {};
  2042. stream_ops = {};
  2043. readMode = 292 | 73;
  2044. writeMode = 146;
  2045. mounted = null;
  2046. constructor(parent, name, mode, rdev) {
  2047. if (!parent) {
  2048. parent = this; // root node sets parent to itself
  2049. }
  2050. this.parent = parent;
  2051. this.mount = parent.mount;
  2052. this.id = FS.nextInode++;
  2053. this.name = name;
  2054. this.mode = mode;
  2055. this.rdev = rdev;
  2056. }
  2057. get read() {
  2058. return (this.mode & this.readMode) === this.readMode;
  2059. }
  2060. set read(val) {
  2061. val ? this.mode |= this.readMode : this.mode &= ~this.readMode;
  2062. }
  2063. get write() {
  2064. return (this.mode & this.writeMode) === this.writeMode;
  2065. }
  2066. set write(val) {
  2067. val ? this.mode |= this.writeMode : this.mode &= ~this.writeMode;
  2068. }
  2069. get isFolder() {
  2070. return FS.isDir(this.mode);
  2071. }
  2072. get isDevice() {
  2073. return FS.isChrdev(this.mode);
  2074. }
  2075. },
  2076. lookupPath(path, opts = {}) {
  2077. path = PATH_FS.resolve(path);
  2078. if (!path) return { path: '', node: null };
  2079. var defaults = {
  2080. follow_mount: true,
  2081. recurse_count: 0
  2082. };
  2083. opts = Object.assign(defaults, opts)
  2084. if (opts.recurse_count > 8) { // max recursive lookup of 8
  2085. throw new FS.ErrnoError(32);
  2086. }
  2087. // split the absolute path
  2088. var parts = path.split('/').filter((p) => !!p);
  2089. // start at the root
  2090. var current = FS.root;
  2091. var current_path = '/';
  2092. for (var i = 0; i < parts.length; i++) {
  2093. var islast = (i === parts.length-1);
  2094. if (islast && opts.parent) {
  2095. // stop resolving
  2096. break;
  2097. }
  2098. current = FS.lookupNode(current, parts[i]);
  2099. current_path = PATH.join2(current_path, parts[i]);
  2100. // jump to the mount's root node if this is a mountpoint
  2101. if (FS.isMountpoint(current)) {
  2102. if (!islast || (islast && opts.follow_mount)) {
  2103. current = current.mounted.root;
  2104. }
  2105. }
  2106. // by default, lookupPath will not follow a symlink if it is the final path component.
  2107. // setting opts.follow = true will override this behavior.
  2108. if (!islast || opts.follow) {
  2109. var count = 0;
  2110. while (FS.isLink(current.mode)) {
  2111. var link = FS.readlink(current_path);
  2112. current_path = PATH_FS.resolve(PATH.dirname(current_path), link);
  2113. var lookup = FS.lookupPath(current_path, { recurse_count: opts.recurse_count + 1 });
  2114. current = lookup.node;
  2115. if (count++ > 40) { // limit max consecutive symlinks to 40 (SYMLOOP_MAX).
  2116. throw new FS.ErrnoError(32);
  2117. }
  2118. }
  2119. }
  2120. }
  2121. return { path: current_path, node: current };
  2122. },
  2123. getPath(node) {
  2124. var path;
  2125. while (true) {
  2126. if (FS.isRoot(node)) {
  2127. var mount = node.mount.mountpoint;
  2128. if (!path) return mount;
  2129. return mount[mount.length-1] !== '/' ? `${mount}/${path}` : mount + path;
  2130. }
  2131. path = path ? `${node.name}/${path}` : node.name;
  2132. node = node.parent;
  2133. }
  2134. },
  2135. hashName(parentid, name) {
  2136. var hash = 0;
  2137. for (var i = 0; i < name.length; i++) {
  2138. hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
  2139. }
  2140. return ((parentid + hash) >>> 0) % FS.nameTable.length;
  2141. },
  2142. hashAddNode(node) {
  2143. var hash = FS.hashName(node.parent.id, node.name);
  2144. node.name_next = FS.nameTable[hash];
  2145. FS.nameTable[hash] = node;
  2146. },
  2147. hashRemoveNode(node) {
  2148. var hash = FS.hashName(node.parent.id, node.name);
  2149. if (FS.nameTable[hash] === node) {
  2150. FS.nameTable[hash] = node.name_next;
  2151. } else {
  2152. var current = FS.nameTable[hash];
  2153. while (current) {
  2154. if (current.name_next === node) {
  2155. current.name_next = node.name_next;
  2156. break;
  2157. }
  2158. current = current.name_next;
  2159. }
  2160. }
  2161. },
  2162. lookupNode(parent, name) {
  2163. var errCode = FS.mayLookup(parent);
  2164. if (errCode) {
  2165. throw new FS.ErrnoError(errCode);
  2166. }
  2167. var hash = FS.hashName(parent.id, name);
  2168. for (var node = FS.nameTable[hash]; node; node = node.name_next) {
  2169. var nodeName = node.name;
  2170. if (node.parent.id === parent.id && nodeName === name) {
  2171. return node;
  2172. }
  2173. }
  2174. // if we failed to find it in the cache, call into the VFS
  2175. return FS.lookup(parent, name);
  2176. },
  2177. createNode(parent, name, mode, rdev) {
  2178. assert(typeof parent == 'object')
  2179. var node = new FS.FSNode(parent, name, mode, rdev);
  2180. FS.hashAddNode(node);
  2181. return node;
  2182. },
  2183. destroyNode(node) {
  2184. FS.hashRemoveNode(node);
  2185. },
  2186. isRoot(node) {
  2187. return node === node.parent;
  2188. },
  2189. isMountpoint(node) {
  2190. return !!node.mounted;
  2191. },
  2192. isFile(mode) {
  2193. return (mode & 61440) === 32768;
  2194. },
  2195. isDir(mode) {
  2196. return (mode & 61440) === 16384;
  2197. },
  2198. isLink(mode) {
  2199. return (mode & 61440) === 40960;
  2200. },
  2201. isChrdev(mode) {
  2202. return (mode & 61440) === 8192;
  2203. },
  2204. isBlkdev(mode) {
  2205. return (mode & 61440) === 24576;
  2206. },
  2207. isFIFO(mode) {
  2208. return (mode & 61440) === 4096;
  2209. },
  2210. isSocket(mode) {
  2211. return (mode & 49152) === 49152;
  2212. },
  2213. flagsToPermissionString(flag) {
  2214. var perms = ['r', 'w', 'rw'][flag & 3];
  2215. if ((flag & 512)) {
  2216. perms += 'w';
  2217. }
  2218. return perms;
  2219. },
  2220. nodePermissions(node, perms) {
  2221. if (FS.ignorePermissions) {
  2222. return 0;
  2223. }
  2224. // return 0 if any user, group or owner bits are set.
  2225. if (perms.includes('r') && !(node.mode & 292)) {
  2226. return 2;
  2227. } else if (perms.includes('w') && !(node.mode & 146)) {
  2228. return 2;
  2229. } else if (perms.includes('x') && !(node.mode & 73)) {
  2230. return 2;
  2231. }
  2232. return 0;
  2233. },
  2234. mayLookup(dir) {
  2235. if (!FS.isDir(dir.mode)) return 54;
  2236. var errCode = FS.nodePermissions(dir, 'x');
  2237. if (errCode) return errCode;
  2238. if (!dir.node_ops.lookup) return 2;
  2239. return 0;
  2240. },
  2241. mayCreate(dir, name) {
  2242. try {
  2243. var node = FS.lookupNode(dir, name);
  2244. return 20;
  2245. } catch (e) {
  2246. }
  2247. return FS.nodePermissions(dir, 'wx');
  2248. },
  2249. mayDelete(dir, name, isdir) {
  2250. var node;
  2251. try {
  2252. node = FS.lookupNode(dir, name);
  2253. } catch (e) {
  2254. return e.errno;
  2255. }
  2256. var errCode = FS.nodePermissions(dir, 'wx');
  2257. if (errCode) {
  2258. return errCode;
  2259. }
  2260. if (isdir) {
  2261. if (!FS.isDir(node.mode)) {
  2262. return 54;
  2263. }
  2264. if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
  2265. return 10;
  2266. }
  2267. } else {
  2268. if (FS.isDir(node.mode)) {
  2269. return 31;
  2270. }
  2271. }
  2272. return 0;
  2273. },
  2274. mayOpen(node, flags) {
  2275. if (!node) {
  2276. return 44;
  2277. }
  2278. if (FS.isLink(node.mode)) {
  2279. return 32;
  2280. } else if (FS.isDir(node.mode)) {
  2281. if (FS.flagsToPermissionString(flags) !== 'r' || // opening for write
  2282. (flags & 512)) { // TODO: check for O_SEARCH? (== search for dir only)
  2283. return 31;
  2284. }
  2285. }
  2286. return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
  2287. },
  2288. MAX_OPEN_FDS:4096,
  2289. nextfd() {
  2290. for (var fd = 0; fd <= FS.MAX_OPEN_FDS; fd++) {
  2291. if (!FS.streams[fd]) {
  2292. return fd;
  2293. }
  2294. }
  2295. throw new FS.ErrnoError(33);
  2296. },
  2297. getStreamChecked(fd) {
  2298. var stream = FS.getStream(fd);
  2299. if (!stream) {
  2300. throw new FS.ErrnoError(8);
  2301. }
  2302. return stream;
  2303. },
  2304. getStream:(fd) => FS.streams[fd],
  2305. createStream(stream, fd = -1) {
  2306. assert(fd >= -1);
  2307. // clone it, so we can return an instance of FSStream
  2308. stream = Object.assign(new FS.FSStream(), stream);
  2309. if (fd == -1) {
  2310. fd = FS.nextfd();
  2311. }
  2312. stream.fd = fd;
  2313. FS.streams[fd] = stream;
  2314. return stream;
  2315. },
  2316. closeStream(fd) {
  2317. FS.streams[fd] = null;
  2318. },
  2319. dupStream(origStream, fd = -1) {
  2320. var stream = FS.createStream(origStream, fd);
  2321. stream.stream_ops?.dup?.(stream);
  2322. return stream;
  2323. },
  2324. chrdev_stream_ops:{
  2325. open(stream) {
  2326. var device = FS.getDevice(stream.node.rdev);
  2327. // override node's stream ops with the device's
  2328. stream.stream_ops = device.stream_ops;
  2329. // forward the open call
  2330. stream.stream_ops.open?.(stream);
  2331. },
  2332. llseek() {
  2333. throw new FS.ErrnoError(70);
  2334. },
  2335. },
  2336. major:(dev) => ((dev) >> 8),
  2337. minor:(dev) => ((dev) & 0xff),
  2338. makedev:(ma, mi) => ((ma) << 8 | (mi)),
  2339. registerDevice(dev, ops) {
  2340. FS.devices[dev] = { stream_ops: ops };
  2341. },
  2342. getDevice:(dev) => FS.devices[dev],
  2343. getMounts(mount) {
  2344. var mounts = [];
  2345. var check = [mount];
  2346. while (check.length) {
  2347. var m = check.pop();
  2348. mounts.push(m);
  2349. check.push(...m.mounts);
  2350. }
  2351. return mounts;
  2352. },
  2353. syncfs(populate, callback) {
  2354. if (typeof populate == 'function') {
  2355. callback = populate;
  2356. populate = false;
  2357. }
  2358. FS.syncFSRequests++;
  2359. if (FS.syncFSRequests > 1) {
  2360. err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`);
  2361. }
  2362. var mounts = FS.getMounts(FS.root.mount);
  2363. var completed = 0;
  2364. function doCallback(errCode) {
  2365. assert(FS.syncFSRequests > 0);
  2366. FS.syncFSRequests--;
  2367. return callback(errCode);
  2368. }
  2369. function done(errCode) {
  2370. if (errCode) {
  2371. if (!done.errored) {
  2372. done.errored = true;
  2373. return doCallback(errCode);
  2374. }
  2375. return;
  2376. }
  2377. if (++completed >= mounts.length) {
  2378. doCallback(null);
  2379. }
  2380. };
  2381. // sync all mounts
  2382. mounts.forEach((mount) => {
  2383. if (!mount.type.syncfs) {
  2384. return done(null);
  2385. }
  2386. mount.type.syncfs(mount, populate, done);
  2387. });
  2388. },
  2389. mount(type, opts, mountpoint) {
  2390. if (typeof type == 'string') {
  2391. // The filesystem was not included, and instead we have an error
  2392. // message stored in the variable.
  2393. throw type;
  2394. }
  2395. var root = mountpoint === '/';
  2396. var pseudo = !mountpoint;
  2397. var node;
  2398. if (root && FS.root) {
  2399. throw new FS.ErrnoError(10);
  2400. } else if (!root && !pseudo) {
  2401. var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
  2402. mountpoint = lookup.path; // use the absolute path
  2403. node = lookup.node;
  2404. if (FS.isMountpoint(node)) {
  2405. throw new FS.ErrnoError(10);
  2406. }
  2407. if (!FS.isDir(node.mode)) {
  2408. throw new FS.ErrnoError(54);
  2409. }
  2410. }
  2411. var mount = {
  2412. type,
  2413. opts,
  2414. mountpoint,
  2415. mounts: []
  2416. };
  2417. // create a root node for the fs
  2418. var mountRoot = type.mount(mount);
  2419. mountRoot.mount = mount;
  2420. mount.root = mountRoot;
  2421. if (root) {
  2422. FS.root = mountRoot;
  2423. } else if (node) {
  2424. // set as a mountpoint
  2425. node.mounted = mount;
  2426. // add the new mount to the current mount's children
  2427. if (node.mount) {
  2428. node.mount.mounts.push(mount);
  2429. }
  2430. }
  2431. return mountRoot;
  2432. },
  2433. unmount(mountpoint) {
  2434. var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
  2435. if (!FS.isMountpoint(lookup.node)) {
  2436. throw new FS.ErrnoError(28);
  2437. }
  2438. // destroy the nodes for this mount, and all its child mounts
  2439. var node = lookup.node;
  2440. var mount = node.mounted;
  2441. var mounts = FS.getMounts(mount);
  2442. Object.keys(FS.nameTable).forEach((hash) => {
  2443. var current = FS.nameTable[hash];
  2444. while (current) {
  2445. var next = current.name_next;
  2446. if (mounts.includes(current.mount)) {
  2447. FS.destroyNode(current);
  2448. }
  2449. current = next;
  2450. }
  2451. });
  2452. // no longer a mountpoint
  2453. node.mounted = null;
  2454. // remove this mount from the child mounts
  2455. var idx = node.mount.mounts.indexOf(mount);
  2456. assert(idx !== -1);
  2457. node.mount.mounts.splice(idx, 1);
  2458. },
  2459. lookup(parent, name) {
  2460. return parent.node_ops.lookup(parent, name);
  2461. },
  2462. mknod(path, mode, dev) {
  2463. var lookup = FS.lookupPath(path, { parent: true });
  2464. var parent = lookup.node;
  2465. var name = PATH.basename(path);
  2466. if (!name || name === '.' || name === '..') {
  2467. throw new FS.ErrnoError(28);
  2468. }
  2469. var errCode = FS.mayCreate(parent, name);
  2470. if (errCode) {
  2471. throw new FS.ErrnoError(errCode);
  2472. }
  2473. if (!parent.node_ops.mknod) {
  2474. throw new FS.ErrnoError(63);
  2475. }
  2476. return parent.node_ops.mknod(parent, name, mode, dev);
  2477. },
  2478. create(path, mode) {
  2479. mode = mode !== undefined ? mode : 438 /* 0666 */;
  2480. mode &= 4095;
  2481. mode |= 32768;
  2482. return FS.mknod(path, mode, 0);
  2483. },
  2484. mkdir(path, mode) {
  2485. mode = mode !== undefined ? mode : 511 /* 0777 */;
  2486. mode &= 511 | 512;
  2487. mode |= 16384;
  2488. return FS.mknod(path, mode, 0);
  2489. },
  2490. mkdirTree(path, mode) {
  2491. var dirs = path.split('/');
  2492. var d = '';
  2493. for (var i = 0; i < dirs.length; ++i) {
  2494. if (!dirs[i]) continue;
  2495. d += '/' + dirs[i];
  2496. try {
  2497. FS.mkdir(d, mode);
  2498. } catch(e) {
  2499. if (e.errno != 20) throw e;
  2500. }
  2501. }
  2502. },
  2503. mkdev(path, mode, dev) {
  2504. if (typeof dev == 'undefined') {
  2505. dev = mode;
  2506. mode = 438 /* 0666 */;
  2507. }
  2508. mode |= 8192;
  2509. return FS.mknod(path, mode, dev);
  2510. },
  2511. symlink(oldpath, newpath) {
  2512. if (!PATH_FS.resolve(oldpath)) {
  2513. throw new FS.ErrnoError(44);
  2514. }
  2515. var lookup = FS.lookupPath(newpath, { parent: true });
  2516. var parent = lookup.node;
  2517. if (!parent) {
  2518. throw new FS.ErrnoError(44);
  2519. }
  2520. var newname = PATH.basename(newpath);
  2521. var errCode = FS.mayCreate(parent, newname);
  2522. if (errCode) {
  2523. throw new FS.ErrnoError(errCode);
  2524. }
  2525. if (!parent.node_ops.symlink) {
  2526. throw new FS.ErrnoError(63);
  2527. }
  2528. return parent.node_ops.symlink(parent, newname, oldpath);
  2529. },
  2530. rename(old_path, new_path) {
  2531. var old_dirname = PATH.dirname(old_path);
  2532. var new_dirname = PATH.dirname(new_path);
  2533. var old_name = PATH.basename(old_path);
  2534. var new_name = PATH.basename(new_path);
  2535. // parents must exist
  2536. var lookup, old_dir, new_dir;
  2537. // let the errors from non existent directories percolate up
  2538. lookup = FS.lookupPath(old_path, { parent: true });
  2539. old_dir = lookup.node;
  2540. lookup = FS.lookupPath(new_path, { parent: true });
  2541. new_dir = lookup.node;
  2542. if (!old_dir || !new_dir) throw new FS.ErrnoError(44);
  2543. // need to be part of the same mount
  2544. if (old_dir.mount !== new_dir.mount) {
  2545. throw new FS.ErrnoError(75);
  2546. }
  2547. // source must exist
  2548. var old_node = FS.lookupNode(old_dir, old_name);
  2549. // old path should not be an ancestor of the new path
  2550. var relative = PATH_FS.relative(old_path, new_dirname);
  2551. if (relative.charAt(0) !== '.') {
  2552. throw new FS.ErrnoError(28);
  2553. }
  2554. // new path should not be an ancestor of the old path
  2555. relative = PATH_FS.relative(new_path, old_dirname);
  2556. if (relative.charAt(0) !== '.') {
  2557. throw new FS.ErrnoError(55);
  2558. }
  2559. // see if the new path already exists
  2560. var new_node;
  2561. try {
  2562. new_node = FS.lookupNode(new_dir, new_name);
  2563. } catch (e) {
  2564. // not fatal
  2565. }
  2566. // early out if nothing needs to change
  2567. if (old_node === new_node) {
  2568. return;
  2569. }
  2570. // we'll need to delete the old entry
  2571. var isdir = FS.isDir(old_node.mode);
  2572. var errCode = FS.mayDelete(old_dir, old_name, isdir);
  2573. if (errCode) {
  2574. throw new FS.ErrnoError(errCode);
  2575. }
  2576. // need delete permissions if we'll be overwriting.
  2577. // need create permissions if new doesn't already exist.
  2578. errCode = new_node ?
  2579. FS.mayDelete(new_dir, new_name, isdir) :
  2580. FS.mayCreate(new_dir, new_name);
  2581. if (errCode) {
  2582. throw new FS.ErrnoError(errCode);
  2583. }
  2584. if (!old_dir.node_ops.rename) {
  2585. throw new FS.ErrnoError(63);
  2586. }
  2587. if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) {
  2588. throw new FS.ErrnoError(10);
  2589. }
  2590. // if we are going to change the parent, check write permissions
  2591. if (new_dir !== old_dir) {
  2592. errCode = FS.nodePermissions(old_dir, 'w');
  2593. if (errCode) {
  2594. throw new FS.ErrnoError(errCode);
  2595. }
  2596. }
  2597. // remove the node from the lookup hash
  2598. FS.hashRemoveNode(old_node);
  2599. // do the underlying fs rename
  2600. try {
  2601. old_dir.node_ops.rename(old_node, new_dir, new_name);
  2602. // update old node (we do this here to avoid each backend
  2603. // needing to)
  2604. old_node.parent = new_dir;
  2605. } catch (e) {
  2606. throw e;
  2607. } finally {
  2608. // add the node back to the hash (in case node_ops.rename
  2609. // changed its name)
  2610. FS.hashAddNode(old_node);
  2611. }
  2612. },
  2613. rmdir(path) {
  2614. var lookup = FS.lookupPath(path, { parent: true });
  2615. var parent = lookup.node;
  2616. var name = PATH.basename(path);
  2617. var node = FS.lookupNode(parent, name);
  2618. var errCode = FS.mayDelete(parent, name, true);
  2619. if (errCode) {
  2620. throw new FS.ErrnoError(errCode);
  2621. }
  2622. if (!parent.node_ops.rmdir) {
  2623. throw new FS.ErrnoError(63);
  2624. }
  2625. if (FS.isMountpoint(node)) {
  2626. throw new FS.ErrnoError(10);
  2627. }
  2628. parent.node_ops.rmdir(parent, name);
  2629. FS.destroyNode(node);
  2630. },
  2631. readdir(path) {
  2632. var lookup = FS.lookupPath(path, { follow: true });
  2633. var node = lookup.node;
  2634. if (!node.node_ops.readdir) {
  2635. throw new FS.ErrnoError(54);
  2636. }
  2637. return node.node_ops.readdir(node);
  2638. },
  2639. unlink(path) {
  2640. var lookup = FS.lookupPath(path, { parent: true });
  2641. var parent = lookup.node;
  2642. if (!parent) {
  2643. throw new FS.ErrnoError(44);
  2644. }
  2645. var name = PATH.basename(path);
  2646. var node = FS.lookupNode(parent, name);
  2647. var errCode = FS.mayDelete(parent, name, false);
  2648. if (errCode) {
  2649. // According to POSIX, we should map EISDIR to EPERM, but
  2650. // we instead do what Linux does (and we must, as we use
  2651. // the musl linux libc).
  2652. throw new FS.ErrnoError(errCode);
  2653. }
  2654. if (!parent.node_ops.unlink) {
  2655. throw new FS.ErrnoError(63);
  2656. }
  2657. if (FS.isMountpoint(node)) {
  2658. throw new FS.ErrnoError(10);
  2659. }
  2660. parent.node_ops.unlink(parent, name);
  2661. FS.destroyNode(node);
  2662. },
  2663. readlink(path) {
  2664. var lookup = FS.lookupPath(path);
  2665. var link = lookup.node;
  2666. if (!link) {
  2667. throw new FS.ErrnoError(44);
  2668. }
  2669. if (!link.node_ops.readlink) {
  2670. throw new FS.ErrnoError(28);
  2671. }
  2672. return PATH_FS.resolve(FS.getPath(link.parent), link.node_ops.readlink(link));
  2673. },
  2674. stat(path, dontFollow) {
  2675. var lookup = FS.lookupPath(path, { follow: !dontFollow });
  2676. var node = lookup.node;
  2677. if (!node) {
  2678. throw new FS.ErrnoError(44);
  2679. }
  2680. if (!node.node_ops.getattr) {
  2681. throw new FS.ErrnoError(63);
  2682. }
  2683. return node.node_ops.getattr(node);
  2684. },
  2685. lstat(path) {
  2686. return FS.stat(path, true);
  2687. },
  2688. chmod(path, mode, dontFollow) {
  2689. var node;
  2690. if (typeof path == 'string') {
  2691. var lookup = FS.lookupPath(path, { follow: !dontFollow });
  2692. node = lookup.node;
  2693. } else {
  2694. node = path;
  2695. }
  2696. if (!node.node_ops.setattr) {
  2697. throw new FS.ErrnoError(63);
  2698. }
  2699. node.node_ops.setattr(node, {
  2700. mode: (mode & 4095) | (node.mode & ~4095),
  2701. timestamp: Date.now()
  2702. });
  2703. },
  2704. lchmod(path, mode) {
  2705. FS.chmod(path, mode, true);
  2706. },
  2707. fchmod(fd, mode) {
  2708. var stream = FS.getStreamChecked(fd);
  2709. FS.chmod(stream.node, mode);
  2710. },
  2711. chown(path, uid, gid, dontFollow) {
  2712. var node;
  2713. if (typeof path == 'string') {
  2714. var lookup = FS.lookupPath(path, { follow: !dontFollow });
  2715. node = lookup.node;
  2716. } else {
  2717. node = path;
  2718. }
  2719. if (!node.node_ops.setattr) {
  2720. throw new FS.ErrnoError(63);
  2721. }
  2722. node.node_ops.setattr(node, {
  2723. timestamp: Date.now()
  2724. // we ignore the uid / gid for now
  2725. });
  2726. },
  2727. lchown(path, uid, gid) {
  2728. FS.chown(path, uid, gid, true);
  2729. },
  2730. fchown(fd, uid, gid) {
  2731. var stream = FS.getStreamChecked(fd);
  2732. FS.chown(stream.node, uid, gid);
  2733. },
  2734. truncate(path, len) {
  2735. if (len < 0) {
  2736. throw new FS.ErrnoError(28);
  2737. }
  2738. var node;
  2739. if (typeof path == 'string') {
  2740. var lookup = FS.lookupPath(path, { follow: true });
  2741. node = lookup.node;
  2742. } else {
  2743. node = path;
  2744. }
  2745. if (!node.node_ops.setattr) {
  2746. throw new FS.ErrnoError(63);
  2747. }
  2748. if (FS.isDir(node.mode)) {
  2749. throw new FS.ErrnoError(31);
  2750. }
  2751. if (!FS.isFile(node.mode)) {
  2752. throw new FS.ErrnoError(28);
  2753. }
  2754. var errCode = FS.nodePermissions(node, 'w');
  2755. if (errCode) {
  2756. throw new FS.ErrnoError(errCode);
  2757. }
  2758. node.node_ops.setattr(node, {
  2759. size: len,
  2760. timestamp: Date.now()
  2761. });
  2762. },
  2763. ftruncate(fd, len) {
  2764. var stream = FS.getStreamChecked(fd);
  2765. if ((stream.flags & 2097155) === 0) {
  2766. throw new FS.ErrnoError(28);
  2767. }
  2768. FS.truncate(stream.node, len);
  2769. },
  2770. utime(path, atime, mtime) {
  2771. var lookup = FS.lookupPath(path, { follow: true });
  2772. var node = lookup.node;
  2773. node.node_ops.setattr(node, {
  2774. timestamp: Math.max(atime, mtime)
  2775. });
  2776. },
  2777. open(path, flags, mode) {
  2778. if (path === "") {
  2779. throw new FS.ErrnoError(44);
  2780. }
  2781. flags = typeof flags == 'string' ? FS_modeStringToFlags(flags) : flags;
  2782. if ((flags & 64)) {
  2783. mode = typeof mode == 'undefined' ? 438 /* 0666 */ : mode;
  2784. mode = (mode & 4095) | 32768;
  2785. } else {
  2786. mode = 0;
  2787. }
  2788. var node;
  2789. if (typeof path == 'object') {
  2790. node = path;
  2791. } else {
  2792. path = PATH.normalize(path);
  2793. try {
  2794. var lookup = FS.lookupPath(path, {
  2795. follow: !(flags & 131072)
  2796. });
  2797. node = lookup.node;
  2798. } catch (e) {
  2799. // ignore
  2800. }
  2801. }
  2802. // perhaps we need to create the node
  2803. var created = false;
  2804. if ((flags & 64)) {
  2805. if (node) {
  2806. // if O_CREAT and O_EXCL are set, error out if the node already exists
  2807. if ((flags & 128)) {
  2808. throw new FS.ErrnoError(20);
  2809. }
  2810. } else {
  2811. // node doesn't exist, try to create it
  2812. node = FS.mknod(path, mode, 0);
  2813. created = true;
  2814. }
  2815. }
  2816. if (!node) {
  2817. throw new FS.ErrnoError(44);
  2818. }
  2819. // can't truncate a device
  2820. if (FS.isChrdev(node.mode)) {
  2821. flags &= ~512;
  2822. }
  2823. // if asked only for a directory, then this must be one
  2824. if ((flags & 65536) && !FS.isDir(node.mode)) {
  2825. throw new FS.ErrnoError(54);
  2826. }
  2827. // check permissions, if this is not a file we just created now (it is ok to
  2828. // create and write to a file with read-only permissions; it is read-only
  2829. // for later use)
  2830. if (!created) {
  2831. var errCode = FS.mayOpen(node, flags);
  2832. if (errCode) {
  2833. throw new FS.ErrnoError(errCode);
  2834. }
  2835. }
  2836. // do truncation if necessary
  2837. if ((flags & 512) && !created) {
  2838. FS.truncate(node, 0);
  2839. }
  2840. // we've already handled these, don't pass down to the underlying vfs
  2841. flags &= ~(128 | 512 | 131072);
  2842. // register the stream with the filesystem
  2843. var stream = FS.createStream({
  2844. node,
  2845. path: FS.getPath(node), // we want the absolute path to the node
  2846. flags,
  2847. seekable: true,
  2848. position: 0,
  2849. stream_ops: node.stream_ops,
  2850. // used by the file family libc calls (fopen, fwrite, ferror, etc.)
  2851. ungotten: [],
  2852. error: false
  2853. });
  2854. // call the new stream's open function
  2855. if (stream.stream_ops.open) {
  2856. stream.stream_ops.open(stream);
  2857. }
  2858. if (Module['logReadFiles'] && !(flags & 1)) {
  2859. if (!(path in FS.readFiles)) {
  2860. FS.readFiles[path] = 1;
  2861. }
  2862. }
  2863. return stream;
  2864. },
  2865. close(stream) {
  2866. if (FS.isClosed(stream)) {
  2867. throw new FS.ErrnoError(8);
  2868. }
  2869. if (stream.getdents) stream.getdents = null; // free readdir state
  2870. try {
  2871. if (stream.stream_ops.close) {
  2872. stream.stream_ops.close(stream);
  2873. }
  2874. } catch (e) {
  2875. throw e;
  2876. } finally {
  2877. FS.closeStream(stream.fd);
  2878. }
  2879. stream.fd = null;
  2880. },
  2881. isClosed(stream) {
  2882. return stream.fd === null;
  2883. },
  2884. llseek(stream, offset, whence) {
  2885. if (FS.isClosed(stream)) {
  2886. throw new FS.ErrnoError(8);
  2887. }
  2888. if (!stream.seekable || !stream.stream_ops.llseek) {
  2889. throw new FS.ErrnoError(70);
  2890. }
  2891. if (whence != 0 && whence != 1 && whence != 2) {
  2892. throw new FS.ErrnoError(28);
  2893. }
  2894. stream.position = stream.stream_ops.llseek(stream, offset, whence);
  2895. stream.ungotten = [];
  2896. return stream.position;
  2897. },
  2898. read(stream, buffer, offset, length, position) {
  2899. assert(offset >= 0);
  2900. if (length < 0 || position < 0) {
  2901. throw new FS.ErrnoError(28);
  2902. }
  2903. if (FS.isClosed(stream)) {
  2904. throw new FS.ErrnoError(8);
  2905. }
  2906. if ((stream.flags & 2097155) === 1) {
  2907. throw new FS.ErrnoError(8);
  2908. }
  2909. if (FS.isDir(stream.node.mode)) {
  2910. throw new FS.ErrnoError(31);
  2911. }
  2912. if (!stream.stream_ops.read) {
  2913. throw new FS.ErrnoError(28);
  2914. }
  2915. var seeking = typeof position != 'undefined';
  2916. if (!seeking) {
  2917. position = stream.position;
  2918. } else if (!stream.seekable) {
  2919. throw new FS.ErrnoError(70);
  2920. }
  2921. var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position);
  2922. if (!seeking) stream.position += bytesRead;
  2923. return bytesRead;
  2924. },
  2925. write(stream, buffer, offset, length, position, canOwn) {
  2926. assert(offset >= 0);
  2927. if (length < 0 || position < 0) {
  2928. throw new FS.ErrnoError(28);
  2929. }
  2930. if (FS.isClosed(stream)) {
  2931. throw new FS.ErrnoError(8);
  2932. }
  2933. if ((stream.flags & 2097155) === 0) {
  2934. throw new FS.ErrnoError(8);
  2935. }
  2936. if (FS.isDir(stream.node.mode)) {
  2937. throw new FS.ErrnoError(31);
  2938. }
  2939. if (!stream.stream_ops.write) {
  2940. throw new FS.ErrnoError(28);
  2941. }
  2942. if (stream.seekable && stream.flags & 1024) {
  2943. // seek to the end before writing in append mode
  2944. FS.llseek(stream, 0, 2);
  2945. }
  2946. var seeking = typeof position != 'undefined';
  2947. if (!seeking) {
  2948. position = stream.position;
  2949. } else if (!stream.seekable) {
  2950. throw new FS.ErrnoError(70);
  2951. }
  2952. var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
  2953. if (!seeking) stream.position += bytesWritten;
  2954. return bytesWritten;
  2955. },
  2956. allocate(stream, offset, length) {
  2957. if (FS.isClosed(stream)) {
  2958. throw new FS.ErrnoError(8);
  2959. }
  2960. if (offset < 0 || length <= 0) {
  2961. throw new FS.ErrnoError(28);
  2962. }
  2963. if ((stream.flags & 2097155) === 0) {
  2964. throw new FS.ErrnoError(8);
  2965. }
  2966. if (!FS.isFile(stream.node.mode) && !FS.isDir(stream.node.mode)) {
  2967. throw new FS.ErrnoError(43);
  2968. }
  2969. if (!stream.stream_ops.allocate) {
  2970. throw new FS.ErrnoError(138);
  2971. }
  2972. stream.stream_ops.allocate(stream, offset, length);
  2973. },
  2974. mmap(stream, length, position, prot, flags) {
  2975. // User requests writing to file (prot & PROT_WRITE != 0).
  2976. // Checking if we have permissions to write to the file unless
  2977. // MAP_PRIVATE flag is set. According to POSIX spec it is possible
  2978. // to write to file opened in read-only mode with MAP_PRIVATE flag,
  2979. // as all modifications will be visible only in the memory of
  2980. // the current process.
  2981. if ((prot & 2) !== 0
  2982. && (flags & 2) === 0
  2983. && (stream.flags & 2097155) !== 2) {
  2984. throw new FS.ErrnoError(2);
  2985. }
  2986. if ((stream.flags & 2097155) === 1) {
  2987. throw new FS.ErrnoError(2);
  2988. }
  2989. if (!stream.stream_ops.mmap) {
  2990. throw new FS.ErrnoError(43);
  2991. }
  2992. if (!length) {
  2993. throw new FS.ErrnoError(28);
  2994. }
  2995. return stream.stream_ops.mmap(stream, length, position, prot, flags);
  2996. },
  2997. msync(stream, buffer, offset, length, mmapFlags) {
  2998. assert(offset >= 0);
  2999. if (!stream.stream_ops.msync) {
  3000. return 0;
  3001. }
  3002. return stream.stream_ops.msync(stream, buffer, offset, length, mmapFlags);
  3003. },
  3004. ioctl(stream, cmd, arg) {
  3005. if (!stream.stream_ops.ioctl) {
  3006. throw new FS.ErrnoError(59);
  3007. }
  3008. return stream.stream_ops.ioctl(stream, cmd, arg);
  3009. },
  3010. readFile(path, opts = {}) {
  3011. opts.flags = opts.flags || 0;
  3012. opts.encoding = opts.encoding || 'binary';
  3013. if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
  3014. throw new Error(`Invalid encoding type "${opts.encoding}"`);
  3015. }
  3016. var ret;
  3017. var stream = FS.open(path, opts.flags);
  3018. var stat = FS.stat(path);
  3019. var length = stat.size;
  3020. var buf = new Uint8Array(length);
  3021. FS.read(stream, buf, 0, length, 0);
  3022. if (opts.encoding === 'utf8') {
  3023. ret = UTF8ArrayToString(buf);
  3024. } else if (opts.encoding === 'binary') {
  3025. ret = buf;
  3026. }
  3027. FS.close(stream);
  3028. return ret;
  3029. },
  3030. writeFile(path, data, opts = {}) {
  3031. opts.flags = opts.flags || 577;
  3032. var stream = FS.open(path, opts.flags, opts.mode);
  3033. if (typeof data == 'string') {
  3034. var buf = new Uint8Array(lengthBytesUTF8(data)+1);
  3035. var actualNumBytes = stringToUTF8Array(data, buf, 0, buf.length);
  3036. FS.write(stream, buf, 0, actualNumBytes, undefined, opts.canOwn);
  3037. } else if (ArrayBuffer.isView(data)) {
  3038. FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn);
  3039. } else {
  3040. throw new Error('Unsupported data type');
  3041. }
  3042. FS.close(stream);
  3043. },
  3044. cwd:() => FS.currentPath,
  3045. chdir(path) {
  3046. var lookup = FS.lookupPath(path, { follow: true });
  3047. if (lookup.node === null) {
  3048. throw new FS.ErrnoError(44);
  3049. }
  3050. if (!FS.isDir(lookup.node.mode)) {
  3051. throw new FS.ErrnoError(54);
  3052. }
  3053. var errCode = FS.nodePermissions(lookup.node, 'x');
  3054. if (errCode) {
  3055. throw new FS.ErrnoError(errCode);
  3056. }
  3057. FS.currentPath = lookup.path;
  3058. },
  3059. createDefaultDirectories() {
  3060. FS.mkdir('/tmp');
  3061. FS.mkdir('/home');
  3062. FS.mkdir('/home/web_user');
  3063. },
  3064. createDefaultDevices() {
  3065. // create /dev
  3066. FS.mkdir('/dev');
  3067. // setup /dev/null
  3068. FS.registerDevice(FS.makedev(1, 3), {
  3069. read: () => 0,
  3070. write: (stream, buffer, offset, length, pos) => length,
  3071. llseek: () => 0,
  3072. });
  3073. FS.mkdev('/dev/null', FS.makedev(1, 3));
  3074. // setup /dev/tty and /dev/tty1
  3075. // stderr needs to print output using err() rather than out()
  3076. // so we register a second tty just for it.
  3077. TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
  3078. TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
  3079. FS.mkdev('/dev/tty', FS.makedev(5, 0));
  3080. FS.mkdev('/dev/tty1', FS.makedev(6, 0));
  3081. // setup /dev/[u]random
  3082. // use a buffer to avoid overhead of individual crypto calls per byte
  3083. var randomBuffer = new Uint8Array(1024), randomLeft = 0;
  3084. var randomByte = () => {
  3085. if (randomLeft === 0) {
  3086. randomLeft = randomFill(randomBuffer).byteLength;
  3087. }
  3088. return randomBuffer[--randomLeft];
  3089. };
  3090. FS.createDevice('/dev', 'random', randomByte);
  3091. FS.createDevice('/dev', 'urandom', randomByte);
  3092. // we're not going to emulate the actual shm device,
  3093. // just create the tmp dirs that reside in it commonly
  3094. FS.mkdir('/dev/shm');
  3095. FS.mkdir('/dev/shm/tmp');
  3096. },
  3097. createSpecialDirectories() {
  3098. // create /proc/self/fd which allows /proc/self/fd/6 => readlink gives the
  3099. // name of the stream for fd 6 (see test_unistd_ttyname)
  3100. FS.mkdir('/proc');
  3101. var proc_self = FS.mkdir('/proc/self');
  3102. FS.mkdir('/proc/self/fd');
  3103. FS.mount({
  3104. mount() {
  3105. var node = FS.createNode(proc_self, 'fd', 16384 | 511 /* 0777 */, 73);
  3106. node.node_ops = {
  3107. lookup(parent, name) {
  3108. var fd = +name;
  3109. var stream = FS.getStreamChecked(fd);
  3110. var ret = {
  3111. parent: null,
  3112. mount: { mountpoint: 'fake' },
  3113. node_ops: { readlink: () => stream.path },
  3114. };
  3115. ret.parent = ret; // make it look like a simple root node
  3116. return ret;
  3117. }
  3118. };
  3119. return node;
  3120. }
  3121. }, {}, '/proc/self/fd');
  3122. },
  3123. createStandardStreams(input, output, error) {
  3124. // TODO deprecate the old functionality of a single
  3125. // input / output callback and that utilizes FS.createDevice
  3126. // and instead require a unique set of stream ops
  3127. // by default, we symlink the standard streams to the
  3128. // default tty devices. however, if the standard streams
  3129. // have been overwritten we create a unique device for
  3130. // them instead.
  3131. if (input) {
  3132. FS.createDevice('/dev', 'stdin', input);
  3133. } else {
  3134. FS.symlink('/dev/tty', '/dev/stdin');
  3135. }
  3136. if (output) {
  3137. FS.createDevice('/dev', 'stdout', null, output);
  3138. } else {
  3139. FS.symlink('/dev/tty', '/dev/stdout');
  3140. }
  3141. if (error) {
  3142. FS.createDevice('/dev', 'stderr', null, error);
  3143. } else {
  3144. FS.symlink('/dev/tty1', '/dev/stderr');
  3145. }
  3146. // open default streams for the stdin, stdout and stderr devices
  3147. var stdin = FS.open('/dev/stdin', 0);
  3148. var stdout = FS.open('/dev/stdout', 1);
  3149. var stderr = FS.open('/dev/stderr', 1);
  3150. assert(stdin.fd === 0, `invalid handle for stdin (${stdin.fd})`);
  3151. assert(stdout.fd === 1, `invalid handle for stdout (${stdout.fd})`);
  3152. assert(stderr.fd === 2, `invalid handle for stderr (${stderr.fd})`);
  3153. },
  3154. staticInit() {
  3155. FS.nameTable = new Array(4096);
  3156. FS.mount(MEMFS, {}, '/');
  3157. FS.createDefaultDirectories();
  3158. FS.createDefaultDevices();
  3159. FS.createSpecialDirectories();
  3160. FS.filesystems = {
  3161. 'MEMFS': MEMFS,
  3162. };
  3163. },
  3164. init(input, output, error) {
  3165. assert(!FS.initialized, 'FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)');
  3166. FS.initialized = true;
  3167. // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here
  3168. input ??= Module['stdin'];
  3169. output ??= Module['stdout'];
  3170. error ??= Module['stderr'];
  3171. FS.createStandardStreams(input, output, error);
  3172. },
  3173. quit() {
  3174. FS.initialized = false;
  3175. // force-flush all streams, so we get musl std streams printed out
  3176. _fflush(0);
  3177. // close all of our streams
  3178. for (var i = 0; i < FS.streams.length; i++) {
  3179. var stream = FS.streams[i];
  3180. if (!stream) {
  3181. continue;
  3182. }
  3183. FS.close(stream);
  3184. }
  3185. },
  3186. findObject(path, dontResolveLastLink) {
  3187. var ret = FS.analyzePath(path, dontResolveLastLink);
  3188. if (!ret.exists) {
  3189. return null;
  3190. }
  3191. return ret.object;
  3192. },
  3193. analyzePath(path, dontResolveLastLink) {
  3194. // operate from within the context of the symlink's target
  3195. try {
  3196. var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
  3197. path = lookup.path;
  3198. } catch (e) {
  3199. }
  3200. var ret = {
  3201. isRoot: false, exists: false, error: 0, name: null, path: null, object: null,
  3202. parentExists: false, parentPath: null, parentObject: null
  3203. };
  3204. try {
  3205. var lookup = FS.lookupPath(path, { parent: true });
  3206. ret.parentExists = true;
  3207. ret.parentPath = lookup.path;
  3208. ret.parentObject = lookup.node;
  3209. ret.name = PATH.basename(path);
  3210. lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
  3211. ret.exists = true;
  3212. ret.path = lookup.path;
  3213. ret.object = lookup.node;
  3214. ret.name = lookup.node.name;
  3215. ret.isRoot = lookup.path === '/';
  3216. } catch (e) {
  3217. ret.error = e.errno;
  3218. };
  3219. return ret;
  3220. },
  3221. createPath(parent, path, canRead, canWrite) {
  3222. parent = typeof parent == 'string' ? parent : FS.getPath(parent);
  3223. var parts = path.split('/').reverse();
  3224. while (parts.length) {
  3225. var part = parts.pop();
  3226. if (!part) continue;
  3227. var current = PATH.join2(parent, part);
  3228. try {
  3229. FS.mkdir(current);
  3230. } catch (e) {
  3231. // ignore EEXIST
  3232. }
  3233. parent = current;
  3234. }
  3235. return current;
  3236. },
  3237. createFile(parent, name, properties, canRead, canWrite) {
  3238. var path = PATH.join2(typeof parent == 'string' ? parent : FS.getPath(parent), name);
  3239. var mode = FS_getMode(canRead, canWrite);
  3240. return FS.create(path, mode);
  3241. },
  3242. createDataFile(parent, name, data, canRead, canWrite, canOwn) {
  3243. var path = name;
  3244. if (parent) {
  3245. parent = typeof parent == 'string' ? parent : FS.getPath(parent);
  3246. path = name ? PATH.join2(parent, name) : parent;
  3247. }
  3248. var mode = FS_getMode(canRead, canWrite);
  3249. var node = FS.create(path, mode);
  3250. if (data) {
  3251. if (typeof data == 'string') {
  3252. var arr = new Array(data.length);
  3253. for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
  3254. data = arr;
  3255. }
  3256. // make sure we can write to the file
  3257. FS.chmod(node, mode | 146);
  3258. var stream = FS.open(node, 577);
  3259. FS.write(stream, data, 0, data.length, 0, canOwn);
  3260. FS.close(stream);
  3261. FS.chmod(node, mode);
  3262. }
  3263. },
  3264. createDevice(parent, name, input, output) {
  3265. var path = PATH.join2(typeof parent == 'string' ? parent : FS.getPath(parent), name);
  3266. var mode = FS_getMode(!!input, !!output);
  3267. FS.createDevice.major ??= 64;
  3268. var dev = FS.makedev(FS.createDevice.major++, 0);
  3269. // Create a fake device that a set of stream ops to emulate
  3270. // the old behavior.
  3271. FS.registerDevice(dev, {
  3272. open(stream) {
  3273. stream.seekable = false;
  3274. },
  3275. close(stream) {
  3276. // flush any pending line data
  3277. if (output?.buffer?.length) {
  3278. output(10);
  3279. }
  3280. },
  3281. read(stream, buffer, offset, length, pos /* ignored */) {
  3282. var bytesRead = 0;
  3283. for (var i = 0; i < length; i++) {
  3284. var result;
  3285. try {
  3286. result = input();
  3287. } catch (e) {
  3288. throw new FS.ErrnoError(29);
  3289. }
  3290. if (result === undefined && bytesRead === 0) {
  3291. throw new FS.ErrnoError(6);
  3292. }
  3293. if (result === null || result === undefined) break;
  3294. bytesRead++;
  3295. buffer[offset+i] = result;
  3296. }
  3297. if (bytesRead) {
  3298. stream.node.timestamp = Date.now();
  3299. }
  3300. return bytesRead;
  3301. },
  3302. write(stream, buffer, offset, length, pos) {
  3303. for (var i = 0; i < length; i++) {
  3304. try {
  3305. output(buffer[offset+i]);
  3306. } catch (e) {
  3307. throw new FS.ErrnoError(29);
  3308. }
  3309. }
  3310. if (length) {
  3311. stream.node.timestamp = Date.now();
  3312. }
  3313. return i;
  3314. }
  3315. });
  3316. return FS.mkdev(path, mode, dev);
  3317. },
  3318. forceLoadFile(obj) {
  3319. if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
  3320. if (typeof XMLHttpRequest != 'undefined') {
  3321. throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.");
  3322. } else { // Command-line.
  3323. try {
  3324. obj.contents = readBinary(obj.url);
  3325. obj.usedBytes = obj.contents.length;
  3326. } catch (e) {
  3327. throw new FS.ErrnoError(29);
  3328. }
  3329. }
  3330. },
  3331. createLazyFile(parent, name, url, canRead, canWrite) {
  3332. // Lazy chunked Uint8Array (implements get and length from Uint8Array).
  3333. // Actual getting is abstracted away for eventual reuse.
  3334. class LazyUint8Array {
  3335. lengthKnown = false;
  3336. chunks = []; // Loaded chunks. Index is the chunk number
  3337. get(idx) {
  3338. if (idx > this.length-1 || idx < 0) {
  3339. return undefined;
  3340. }
  3341. var chunkOffset = idx % this.chunkSize;
  3342. var chunkNum = (idx / this.chunkSize)|0;
  3343. return this.getter(chunkNum)[chunkOffset];
  3344. }
  3345. setDataGetter(getter) {
  3346. this.getter = getter;
  3347. }
  3348. cacheLength() {
  3349. // Find length
  3350. var xhr = new XMLHttpRequest();
  3351. xhr.open('HEAD', url, false);
  3352. xhr.send(null);
  3353. if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
  3354. var datalength = Number(xhr.getResponseHeader("Content-length"));
  3355. var header;
  3356. var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";
  3357. var usesGzip = (header = xhr.getResponseHeader("Content-Encoding")) && header === "gzip";
  3358. var chunkSize = 1024*1024; // Chunk size in bytes
  3359. if (!hasByteServing) chunkSize = datalength;
  3360. // Function to get a range from the remote URL.
  3361. var doXHR = (from, to) => {
  3362. if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!");
  3363. if (to > datalength-1) throw new Error("only " + datalength + " bytes available! programmer error!");
  3364. // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
  3365. var xhr = new XMLHttpRequest();
  3366. xhr.open('GET', url, false);
  3367. if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);
  3368. // Some hints to the browser that we want binary data.
  3369. xhr.responseType = 'arraybuffer';
  3370. if (xhr.overrideMimeType) {
  3371. xhr.overrideMimeType('text/plain; charset=x-user-defined');
  3372. }
  3373. xhr.send(null);
  3374. if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
  3375. if (xhr.response !== undefined) {
  3376. return new Uint8Array(/** @type{Array<number>} */(xhr.response || []));
  3377. }
  3378. return intArrayFromString(xhr.responseText || '', true);
  3379. };
  3380. var lazyArray = this;
  3381. lazyArray.setDataGetter((chunkNum) => {
  3382. var start = chunkNum * chunkSize;
  3383. var end = (chunkNum+1) * chunkSize - 1; // including this byte
  3384. end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block
  3385. if (typeof lazyArray.chunks[chunkNum] == 'undefined') {
  3386. lazyArray.chunks[chunkNum] = doXHR(start, end);
  3387. }
  3388. if (typeof lazyArray.chunks[chunkNum] == 'undefined') throw new Error('doXHR failed!');
  3389. return lazyArray.chunks[chunkNum];
  3390. });
  3391. if (usesGzip || !datalength) {
  3392. // if the server uses gzip or doesn't supply the length, we have to download the whole file to get the (uncompressed) length
  3393. chunkSize = datalength = 1; // this will force getter(0)/doXHR do download the whole file
  3394. datalength = this.getter(0).length;
  3395. chunkSize = datalength;
  3396. out("LazyFiles on gzip forces download of the whole file when length is accessed");
  3397. }
  3398. this._length = datalength;
  3399. this._chunkSize = chunkSize;
  3400. this.lengthKnown = true;
  3401. }
  3402. get length() {
  3403. if (!this.lengthKnown) {
  3404. this.cacheLength();
  3405. }
  3406. return this._length;
  3407. }
  3408. get chunkSize() {
  3409. if (!this.lengthKnown) {
  3410. this.cacheLength();
  3411. }
  3412. return this._chunkSize;
  3413. }
  3414. }
  3415. if (typeof XMLHttpRequest != 'undefined') {
  3416. if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc';
  3417. var lazyArray = new LazyUint8Array();
  3418. var properties = { isDevice: false, contents: lazyArray };
  3419. } else {
  3420. var properties = { isDevice: false, url: url };
  3421. }
  3422. var node = FS.createFile(parent, name, properties, canRead, canWrite);
  3423. // This is a total hack, but I want to get this lazy file code out of the
  3424. // core of MEMFS. If we want to keep this lazy file concept I feel it should
  3425. // be its own thin LAZYFS proxying calls to MEMFS.
  3426. if (properties.contents) {
  3427. node.contents = properties.contents;
  3428. } else if (properties.url) {
  3429. node.contents = null;
  3430. node.url = properties.url;
  3431. }
  3432. // Add a function that defers querying the file size until it is asked the first time.
  3433. Object.defineProperties(node, {
  3434. usedBytes: {
  3435. get: function() { return this.contents.length; }
  3436. }
  3437. });
  3438. // override each stream op with one that tries to force load the lazy file first
  3439. var stream_ops = {};
  3440. var keys = Object.keys(node.stream_ops);
  3441. keys.forEach((key) => {
  3442. var fn = node.stream_ops[key];
  3443. stream_ops[key] = (...args) => {
  3444. FS.forceLoadFile(node);
  3445. return fn(...args);
  3446. };
  3447. });
  3448. function writeChunks(stream, buffer, offset, length, position) {
  3449. var contents = stream.node.contents;
  3450. if (position >= contents.length)
  3451. return 0;
  3452. var size = Math.min(contents.length - position, length);
  3453. assert(size >= 0);
  3454. if (contents.slice) { // normal array
  3455. for (var i = 0; i < size; i++) {
  3456. buffer[offset + i] = contents[position + i];
  3457. }
  3458. } else {
  3459. for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR
  3460. buffer[offset + i] = contents.get(position + i);
  3461. }
  3462. }
  3463. return size;
  3464. }
  3465. // use a custom read function
  3466. stream_ops.read = (stream, buffer, offset, length, position) => {
  3467. FS.forceLoadFile(node);
  3468. return writeChunks(stream, buffer, offset, length, position)
  3469. };
  3470. // use a custom mmap function
  3471. stream_ops.mmap = (stream, length, position, prot, flags) => {
  3472. FS.forceLoadFile(node);
  3473. var ptr = mmapAlloc(length);
  3474. if (!ptr) {
  3475. throw new FS.ErrnoError(48);
  3476. }
  3477. writeChunks(stream, HEAP8, ptr, length, position);
  3478. return { ptr, allocated: true };
  3479. };
  3480. node.stream_ops = stream_ops;
  3481. return node;
  3482. },
  3483. absolutePath() {
  3484. abort('FS.absolutePath has been removed; use PATH_FS.resolve instead');
  3485. },
  3486. createFolder() {
  3487. abort('FS.createFolder has been removed; use FS.mkdir instead');
  3488. },
  3489. createLink() {
  3490. abort('FS.createLink has been removed; use FS.symlink instead');
  3491. },
  3492. joinPath() {
  3493. abort('FS.joinPath has been removed; use PATH.join instead');
  3494. },
  3495. mmapAlloc() {
  3496. abort('FS.mmapAlloc has been replaced by the top level function mmapAlloc');
  3497. },
  3498. standardizePath() {
  3499. abort('FS.standardizePath has been removed; use PATH.normalize instead');
  3500. },
  3501. };
  3502. var SYSCALLS = {
  3503. DEFAULT_POLLMASK:5,
  3504. calculateAt(dirfd, path, allowEmpty) {
  3505. if (PATH.isAbs(path)) {
  3506. return path;
  3507. }
  3508. // relative path
  3509. var dir;
  3510. if (dirfd === -100) {
  3511. dir = FS.cwd();
  3512. } else {
  3513. var dirstream = SYSCALLS.getStreamFromFD(dirfd);
  3514. dir = dirstream.path;
  3515. }
  3516. if (path.length == 0) {
  3517. if (!allowEmpty) {
  3518. throw new FS.ErrnoError(44);;
  3519. }
  3520. return dir;
  3521. }
  3522. return PATH.join2(dir, path);
  3523. },
  3524. doStat(func, path, buf) {
  3525. var stat = func(path);
  3526. HEAP32[((buf)>>2)] = stat.dev;
  3527. HEAP32[(((buf)+(4))>>2)] = stat.mode;
  3528. HEAPU32[(((buf)+(8))>>2)] = stat.nlink;
  3529. HEAP32[(((buf)+(12))>>2)] = stat.uid;
  3530. HEAP32[(((buf)+(16))>>2)] = stat.gid;
  3531. HEAP32[(((buf)+(20))>>2)] = stat.rdev;
  3532. HEAP64[(((buf)+(24))>>3)] = BigInt(stat.size);
  3533. HEAP32[(((buf)+(32))>>2)] = 4096;
  3534. HEAP32[(((buf)+(36))>>2)] = stat.blocks;
  3535. var atime = stat.atime.getTime();
  3536. var mtime = stat.mtime.getTime();
  3537. var ctime = stat.ctime.getTime();
  3538. HEAP64[(((buf)+(40))>>3)] = BigInt(Math.floor(atime / 1000));
  3539. HEAPU32[(((buf)+(48))>>2)] = (atime % 1000) * 1000 * 1000;
  3540. HEAP64[(((buf)+(56))>>3)] = BigInt(Math.floor(mtime / 1000));
  3541. HEAPU32[(((buf)+(64))>>2)] = (mtime % 1000) * 1000 * 1000;
  3542. HEAP64[(((buf)+(72))>>3)] = BigInt(Math.floor(ctime / 1000));
  3543. HEAPU32[(((buf)+(80))>>2)] = (ctime % 1000) * 1000 * 1000;
  3544. HEAP64[(((buf)+(88))>>3)] = BigInt(stat.ino);
  3545. return 0;
  3546. },
  3547. doMsync(addr, stream, len, flags, offset) {
  3548. if (!FS.isFile(stream.node.mode)) {
  3549. throw new FS.ErrnoError(43);
  3550. }
  3551. if (flags & 2) {
  3552. // MAP_PRIVATE calls need not to be synced back to underlying fs
  3553. return 0;
  3554. }
  3555. var buffer = HEAPU8.slice(addr, addr + len);
  3556. FS.msync(stream, buffer, offset, len, flags);
  3557. },
  3558. getStreamFromFD(fd) {
  3559. var stream = FS.getStreamChecked(fd);
  3560. return stream;
  3561. },
  3562. varargs:undefined,
  3563. getStr(ptr) {
  3564. var ret = UTF8ToString(ptr);
  3565. return ret;
  3566. },
  3567. };
  3568. function ___syscall_fcntl64(fd, cmd, varargs) {
  3569. SYSCALLS.varargs = varargs;
  3570. try {
  3571. var stream = SYSCALLS.getStreamFromFD(fd);
  3572. switch (cmd) {
  3573. case 0: {
  3574. var arg = syscallGetVarargI();
  3575. if (arg < 0) {
  3576. return -28;
  3577. }
  3578. while (FS.streams[arg]) {
  3579. arg++;
  3580. }
  3581. var newStream;
  3582. newStream = FS.dupStream(stream, arg);
  3583. return newStream.fd;
  3584. }
  3585. case 1:
  3586. case 2:
  3587. return 0; // FD_CLOEXEC makes no sense for a single process.
  3588. case 3:
  3589. return stream.flags;
  3590. case 4: {
  3591. var arg = syscallGetVarargI();
  3592. stream.flags |= arg;
  3593. return 0;
  3594. }
  3595. case 12: {
  3596. var arg = syscallGetVarargP();
  3597. var offset = 0;
  3598. // We're always unlocked.
  3599. HEAP16[(((arg)+(offset))>>1)] = 2;
  3600. return 0;
  3601. }
  3602. case 13:
  3603. case 14:
  3604. return 0; // Pretend that the locking is successful.
  3605. }
  3606. return -28;
  3607. } catch (e) {
  3608. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  3609. return -e.errno;
  3610. }
  3611. }
  3612. function ___syscall_fstat64(fd, buf) {
  3613. try {
  3614. var stream = SYSCALLS.getStreamFromFD(fd);
  3615. return SYSCALLS.doStat(FS.stat, stream.path, buf);
  3616. } catch (e) {
  3617. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  3618. return -e.errno;
  3619. }
  3620. }
  3621. function ___syscall_ioctl(fd, op, varargs) {
  3622. SYSCALLS.varargs = varargs;
  3623. try {
  3624. var stream = SYSCALLS.getStreamFromFD(fd);
  3625. switch (op) {
  3626. case 21509: {
  3627. if (!stream.tty) return -59;
  3628. return 0;
  3629. }
  3630. case 21505: {
  3631. if (!stream.tty) return -59;
  3632. if (stream.tty.ops.ioctl_tcgets) {
  3633. var termios = stream.tty.ops.ioctl_tcgets(stream);
  3634. var argp = syscallGetVarargP();
  3635. HEAP32[((argp)>>2)] = termios.c_iflag || 0;
  3636. HEAP32[(((argp)+(4))>>2)] = termios.c_oflag || 0;
  3637. HEAP32[(((argp)+(8))>>2)] = termios.c_cflag || 0;
  3638. HEAP32[(((argp)+(12))>>2)] = termios.c_lflag || 0;
  3639. for (var i = 0; i < 32; i++) {
  3640. HEAP8[(argp + i)+(17)] = termios.c_cc[i] || 0;
  3641. }
  3642. return 0;
  3643. }
  3644. return 0;
  3645. }
  3646. case 21510:
  3647. case 21511:
  3648. case 21512: {
  3649. if (!stream.tty) return -59;
  3650. return 0; // no-op, not actually adjusting terminal settings
  3651. }
  3652. case 21506:
  3653. case 21507:
  3654. case 21508: {
  3655. if (!stream.tty) return -59;
  3656. if (stream.tty.ops.ioctl_tcsets) {
  3657. var argp = syscallGetVarargP();
  3658. var c_iflag = HEAP32[((argp)>>2)];
  3659. var c_oflag = HEAP32[(((argp)+(4))>>2)];
  3660. var c_cflag = HEAP32[(((argp)+(8))>>2)];
  3661. var c_lflag = HEAP32[(((argp)+(12))>>2)];
  3662. var c_cc = []
  3663. for (var i = 0; i < 32; i++) {
  3664. c_cc.push(HEAP8[(argp + i)+(17)]);
  3665. }
  3666. return stream.tty.ops.ioctl_tcsets(stream.tty, op, { c_iflag, c_oflag, c_cflag, c_lflag, c_cc });
  3667. }
  3668. return 0; // no-op, not actually adjusting terminal settings
  3669. }
  3670. case 21519: {
  3671. if (!stream.tty) return -59;
  3672. var argp = syscallGetVarargP();
  3673. HEAP32[((argp)>>2)] = 0;
  3674. return 0;
  3675. }
  3676. case 21520: {
  3677. if (!stream.tty) return -59;
  3678. return -28; // not supported
  3679. }
  3680. case 21531: {
  3681. var argp = syscallGetVarargP();
  3682. return FS.ioctl(stream, op, argp);
  3683. }
  3684. case 21523: {
  3685. // TODO: in theory we should write to the winsize struct that gets
  3686. // passed in, but for now musl doesn't read anything on it
  3687. if (!stream.tty) return -59;
  3688. if (stream.tty.ops.ioctl_tiocgwinsz) {
  3689. var winsize = stream.tty.ops.ioctl_tiocgwinsz(stream.tty);
  3690. var argp = syscallGetVarargP();
  3691. HEAP16[((argp)>>1)] = winsize[0];
  3692. HEAP16[(((argp)+(2))>>1)] = winsize[1];
  3693. }
  3694. return 0;
  3695. }
  3696. case 21524: {
  3697. // TODO: technically, this ioctl call should change the window size.
  3698. // but, since emscripten doesn't have any concept of a terminal window
  3699. // yet, we'll just silently throw it away as we do TIOCGWINSZ
  3700. if (!stream.tty) return -59;
  3701. return 0;
  3702. }
  3703. case 21515: {
  3704. if (!stream.tty) return -59;
  3705. return 0;
  3706. }
  3707. default: return -28; // not supported
  3708. }
  3709. } catch (e) {
  3710. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  3711. return -e.errno;
  3712. }
  3713. }
  3714. function ___syscall_lstat64(path, buf) {
  3715. try {
  3716. path = SYSCALLS.getStr(path);
  3717. return SYSCALLS.doStat(FS.lstat, path, buf);
  3718. } catch (e) {
  3719. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  3720. return -e.errno;
  3721. }
  3722. }
  3723. function ___syscall_newfstatat(dirfd, path, buf, flags) {
  3724. try {
  3725. path = SYSCALLS.getStr(path);
  3726. var nofollow = flags & 256;
  3727. var allowEmpty = flags & 4096;
  3728. flags = flags & (~6400);
  3729. assert(!flags, `unknown flags in __syscall_newfstatat: ${flags}`);
  3730. path = SYSCALLS.calculateAt(dirfd, path, allowEmpty);
  3731. return SYSCALLS.doStat(nofollow ? FS.lstat : FS.stat, path, buf);
  3732. } catch (e) {
  3733. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  3734. return -e.errno;
  3735. }
  3736. }
  3737. function ___syscall_openat(dirfd, path, flags, varargs) {
  3738. SYSCALLS.varargs = varargs;
  3739. try {
  3740. path = SYSCALLS.getStr(path);
  3741. path = SYSCALLS.calculateAt(dirfd, path);
  3742. var mode = varargs ? syscallGetVarargI() : 0;
  3743. return FS.open(path, flags, mode).fd;
  3744. } catch (e) {
  3745. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  3746. return -e.errno;
  3747. }
  3748. }
  3749. function ___syscall_stat64(path, buf) {
  3750. try {
  3751. path = SYSCALLS.getStr(path);
  3752. return SYSCALLS.doStat(FS.stat, path, buf);
  3753. } catch (e) {
  3754. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  3755. return -e.errno;
  3756. }
  3757. }
  3758. var __abort_js = () => {
  3759. abort('native code called abort()');
  3760. };
  3761. var nowIsMonotonic = 1;
  3762. var __emscripten_get_now_is_monotonic = () => nowIsMonotonic;
  3763. var __emscripten_throw_longjmp = () => {
  3764. throw Infinity;
  3765. };
  3766. var INT53_MAX = 9007199254740992;
  3767. var INT53_MIN = -9007199254740992;
  3768. var bigintToI53Checked = (num) => (num < INT53_MIN || num > INT53_MAX) ? NaN : Number(num);
  3769. function __gmtime_js(time, tmPtr) {
  3770. time = bigintToI53Checked(time);
  3771. var date = new Date(time * 1000);
  3772. HEAP32[((tmPtr)>>2)] = date.getUTCSeconds();
  3773. HEAP32[(((tmPtr)+(4))>>2)] = date.getUTCMinutes();
  3774. HEAP32[(((tmPtr)+(8))>>2)] = date.getUTCHours();
  3775. HEAP32[(((tmPtr)+(12))>>2)] = date.getUTCDate();
  3776. HEAP32[(((tmPtr)+(16))>>2)] = date.getUTCMonth();
  3777. HEAP32[(((tmPtr)+(20))>>2)] = date.getUTCFullYear()-1900;
  3778. HEAP32[(((tmPtr)+(24))>>2)] = date.getUTCDay();
  3779. var start = Date.UTC(date.getUTCFullYear(), 0, 1, 0, 0, 0, 0);
  3780. var yday = ((date.getTime() - start) / (1000 * 60 * 60 * 24))|0;
  3781. HEAP32[(((tmPtr)+(28))>>2)] = yday;
  3782. ;
  3783. }
  3784. var stringToUTF8 = (str, outPtr, maxBytesToWrite) => {
  3785. assert(typeof maxBytesToWrite == 'number', 'stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!');
  3786. return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);
  3787. };
  3788. var __tzset_js = (timezone, daylight, std_name, dst_name) => {
  3789. // TODO: Use (malleable) environment variables instead of system settings.
  3790. var currentYear = new Date().getFullYear();
  3791. var winter = new Date(currentYear, 0, 1);
  3792. var summer = new Date(currentYear, 6, 1);
  3793. var winterOffset = winter.getTimezoneOffset();
  3794. var summerOffset = summer.getTimezoneOffset();
  3795. // Local standard timezone offset. Local standard time is not adjusted for
  3796. // daylight savings. This code uses the fact that getTimezoneOffset returns
  3797. // a greater value during Standard Time versus Daylight Saving Time (DST).
  3798. // Thus it determines the expected output during Standard Time, and it
  3799. // compares whether the output of the given date the same (Standard) or less
  3800. // (DST).
  3801. var stdTimezoneOffset = Math.max(winterOffset, summerOffset);
  3802. // timezone is specified as seconds west of UTC ("The external variable
  3803. // `timezone` shall be set to the difference, in seconds, between
  3804. // Coordinated Universal Time (UTC) and local standard time."), the same
  3805. // as returned by stdTimezoneOffset.
  3806. // See http://pubs.opengroup.org/onlinepubs/009695399/functions/tzset.html
  3807. HEAPU32[((timezone)>>2)] = stdTimezoneOffset * 60;
  3808. HEAP32[((daylight)>>2)] = Number(winterOffset != summerOffset);
  3809. var extractZone = (timezoneOffset) => {
  3810. // Why inverse sign?
  3811. // Read here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset
  3812. var sign = timezoneOffset >= 0 ? "-" : "+";
  3813. var absOffset = Math.abs(timezoneOffset)
  3814. var hours = String(Math.floor(absOffset / 60)).padStart(2, "0");
  3815. var minutes = String(absOffset % 60).padStart(2, "0");
  3816. return `UTC${sign}${hours}${minutes}`;
  3817. }
  3818. var winterName = extractZone(winterOffset);
  3819. var summerName = extractZone(summerOffset);
  3820. assert(winterName);
  3821. assert(summerName);
  3822. assert(lengthBytesUTF8(winterName) <= 16, `timezone name truncated to fit in TZNAME_MAX (${winterName})`);
  3823. assert(lengthBytesUTF8(summerName) <= 16, `timezone name truncated to fit in TZNAME_MAX (${summerName})`);
  3824. if (summerOffset < winterOffset) {
  3825. // Northern hemisphere
  3826. stringToUTF8(winterName, std_name, 17);
  3827. stringToUTF8(summerName, dst_name, 17);
  3828. } else {
  3829. stringToUTF8(winterName, dst_name, 17);
  3830. stringToUTF8(summerName, std_name, 17);
  3831. }
  3832. };
  3833. var handleException = (e) => {
  3834. // Certain exception types we do not treat as errors since they are used for
  3835. // internal control flow.
  3836. // 1. ExitStatus, which is thrown by exit()
  3837. // 2. "unwind", which is thrown by emscripten_unwind_to_js_event_loop() and others
  3838. // that wish to return to JS event loop.
  3839. if (e instanceof ExitStatus || e == 'unwind') {
  3840. return EXITSTATUS;
  3841. }
  3842. checkStackCookie();
  3843. if (e instanceof WebAssembly.RuntimeError) {
  3844. if (_emscripten_stack_get_current() <= 0) {
  3845. err('Stack overflow detected. You can try increasing -sSTACK_SIZE (currently set to 65536)');
  3846. }
  3847. }
  3848. quit_(1, e);
  3849. };
  3850. var runtimeKeepaliveCounter = 0;
  3851. var keepRuntimeAlive = () => noExitRuntime || runtimeKeepaliveCounter > 0;
  3852. var _proc_exit = (code) => {
  3853. EXITSTATUS = code;
  3854. if (!keepRuntimeAlive()) {
  3855. Module['onExit']?.(code);
  3856. ABORT = true;
  3857. }
  3858. quit_(code, new ExitStatus(code));
  3859. };
  3860. /** @suppress {duplicate } */
  3861. /** @param {boolean|number=} implicit */
  3862. var exitJS = (status, implicit) => {
  3863. EXITSTATUS = status;
  3864. if (!keepRuntimeAlive()) {
  3865. exitRuntime();
  3866. }
  3867. // if exit() was called explicitly, warn the user if the runtime isn't actually being shut down
  3868. if (keepRuntimeAlive() && !implicit) {
  3869. var msg = `program exited (with status: ${status}), but keepRuntimeAlive() is set (counter=${runtimeKeepaliveCounter}) due to an async operation, so halting execution but not exiting the runtime or preventing further async execution (you can use emscripten_force_exit, if you want to force a true shutdown)`;
  3870. err(msg);
  3871. }
  3872. _proc_exit(status);
  3873. };
  3874. var _exit = exitJS;
  3875. var maybeExit = () => {
  3876. if (runtimeExited) {
  3877. return;
  3878. }
  3879. if (!keepRuntimeAlive()) {
  3880. try {
  3881. _exit(EXITSTATUS);
  3882. } catch (e) {
  3883. handleException(e);
  3884. }
  3885. }
  3886. };
  3887. var callUserCallback = (func) => {
  3888. if (runtimeExited || ABORT) {
  3889. err('user callback triggered after runtime exited or application aborted. Ignoring.');
  3890. return;
  3891. }
  3892. try {
  3893. func();
  3894. maybeExit();
  3895. } catch (e) {
  3896. handleException(e);
  3897. }
  3898. };
  3899. var runtimeKeepalivePush = () => {
  3900. runtimeKeepaliveCounter += 1;
  3901. };
  3902. var runtimeKeepalivePop = () => {
  3903. assert(runtimeKeepaliveCounter > 0);
  3904. runtimeKeepaliveCounter -= 1;
  3905. };
  3906. /** @param {number=} timeout */
  3907. var safeSetTimeout = (func, timeout) => {
  3908. runtimeKeepalivePush();
  3909. return setTimeout(() => {
  3910. runtimeKeepalivePop();
  3911. callUserCallback(func);
  3912. }, timeout);
  3913. };
  3914. var Browser = {
  3915. useWebGL:false,
  3916. isFullscreen:false,
  3917. pointerLock:false,
  3918. moduleContextCreatedCallbacks:[],
  3919. workers:[],
  3920. preloadedImages:{
  3921. },
  3922. preloadedAudios:{
  3923. },
  3924. init() {
  3925. if (Browser.initted) return;
  3926. Browser.initted = true;
  3927. // Support for plugins that can process preloaded files. You can add more of these to
  3928. // your app by creating and appending to preloadPlugins.
  3929. //
  3930. // Each plugin is asked if it can handle a file based on the file's name. If it can,
  3931. // it is given the file's raw data. When it is done, it calls a callback with the file's
  3932. // (possibly modified) data. For example, a plugin might decompress a file, or it
  3933. // might create some side data structure for use later (like an Image element, etc.).
  3934. var imagePlugin = {};
  3935. imagePlugin['canHandle'] = function imagePlugin_canHandle(name) {
  3936. return !Module['noImageDecoding'] && /\.(jpg|jpeg|png|bmp|webp)$/i.test(name);
  3937. };
  3938. imagePlugin['handle'] = function imagePlugin_handle(byteArray, name, onload, onerror) {
  3939. var b = new Blob([byteArray], { type: Browser.getMimetype(name) });
  3940. if (b.size !== byteArray.length) { // Safari bug #118630
  3941. // Safari's Blob can only take an ArrayBuffer
  3942. b = new Blob([(new Uint8Array(byteArray)).buffer], { type: Browser.getMimetype(name) });
  3943. }
  3944. var url = URL.createObjectURL(b);
  3945. assert(typeof url == 'string', 'createObjectURL must return a url as a string');
  3946. var img = new Image();
  3947. img.onload = () => {
  3948. assert(img.complete, `Image ${name} could not be decoded`);
  3949. var canvas = /** @type {!HTMLCanvasElement} */ (document.createElement('canvas'));
  3950. canvas.width = img.width;
  3951. canvas.height = img.height;
  3952. var ctx = canvas.getContext('2d');
  3953. ctx.drawImage(img, 0, 0);
  3954. Browser.preloadedImages[name] = canvas;
  3955. URL.revokeObjectURL(url);
  3956. onload?.(byteArray);
  3957. };
  3958. img.onerror = (event) => {
  3959. err(`Image ${url} could not be decoded`);
  3960. onerror?.();
  3961. };
  3962. img.src = url;
  3963. };
  3964. preloadPlugins.push(imagePlugin);
  3965. var audioPlugin = {};
  3966. audioPlugin['canHandle'] = function audioPlugin_canHandle(name) {
  3967. return !Module['noAudioDecoding'] && name.substr(-4) in { '.ogg': 1, '.wav': 1, '.mp3': 1 };
  3968. };
  3969. audioPlugin['handle'] = function audioPlugin_handle(byteArray, name, onload, onerror) {
  3970. var done = false;
  3971. function finish(audio) {
  3972. if (done) return;
  3973. done = true;
  3974. Browser.preloadedAudios[name] = audio;
  3975. onload?.(byteArray);
  3976. }
  3977. function fail() {
  3978. if (done) return;
  3979. done = true;
  3980. Browser.preloadedAudios[name] = new Audio(); // empty shim
  3981. onerror?.();
  3982. }
  3983. var b = new Blob([byteArray], { type: Browser.getMimetype(name) });
  3984. var url = URL.createObjectURL(b); // XXX we never revoke this!
  3985. assert(typeof url == 'string', 'createObjectURL must return a url as a string');
  3986. var audio = new Audio();
  3987. audio.addEventListener('canplaythrough', () => finish(audio), false); // use addEventListener due to chromium bug 124926
  3988. audio.onerror = function audio_onerror(event) {
  3989. if (done) return;
  3990. err(`warning: browser could not fully decode audio ${name}, trying slower base64 approach`);
  3991. function encode64(data) {
  3992. var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  3993. var PAD = '=';
  3994. var ret = '';
  3995. var leftchar = 0;
  3996. var leftbits = 0;
  3997. for (var i = 0; i < data.length; i++) {
  3998. leftchar = (leftchar << 8) | data[i];
  3999. leftbits += 8;
  4000. while (leftbits >= 6) {
  4001. var curr = (leftchar >> (leftbits-6)) & 0x3f;
  4002. leftbits -= 6;
  4003. ret += BASE[curr];
  4004. }
  4005. }
  4006. if (leftbits == 2) {
  4007. ret += BASE[(leftchar&3) << 4];
  4008. ret += PAD + PAD;
  4009. } else if (leftbits == 4) {
  4010. ret += BASE[(leftchar&0xf) << 2];
  4011. ret += PAD;
  4012. }
  4013. return ret;
  4014. }
  4015. audio.src = 'data:audio/x-' + name.substr(-3) + ';base64,' + encode64(byteArray);
  4016. finish(audio); // we don't wait for confirmation this worked - but it's worth trying
  4017. };
  4018. audio.src = url;
  4019. // workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror
  4020. safeSetTimeout(() => {
  4021. finish(audio); // try to use it even though it is not necessarily ready to play
  4022. }, 10000);
  4023. };
  4024. preloadPlugins.push(audioPlugin);
  4025. // Canvas event setup
  4026. function pointerLockChange() {
  4027. Browser.pointerLock = document['pointerLockElement'] === Module['canvas'] ||
  4028. document['mozPointerLockElement'] === Module['canvas'] ||
  4029. document['webkitPointerLockElement'] === Module['canvas'] ||
  4030. document['msPointerLockElement'] === Module['canvas'];
  4031. }
  4032. var canvas = Module['canvas'];
  4033. if (canvas) {
  4034. // forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module
  4035. // Module['forcedAspectRatio'] = 4 / 3;
  4036. canvas.requestPointerLock = canvas['requestPointerLock'] ||
  4037. canvas['mozRequestPointerLock'] ||
  4038. canvas['webkitRequestPointerLock'] ||
  4039. canvas['msRequestPointerLock'] ||
  4040. (() => {});
  4041. canvas.exitPointerLock = document['exitPointerLock'] ||
  4042. document['mozExitPointerLock'] ||
  4043. document['webkitExitPointerLock'] ||
  4044. document['msExitPointerLock'] ||
  4045. (() => {}); // no-op if function does not exist
  4046. canvas.exitPointerLock = canvas.exitPointerLock.bind(document);
  4047. document.addEventListener('pointerlockchange', pointerLockChange, false);
  4048. document.addEventListener('mozpointerlockchange', pointerLockChange, false);
  4049. document.addEventListener('webkitpointerlockchange', pointerLockChange, false);
  4050. document.addEventListener('mspointerlockchange', pointerLockChange, false);
  4051. if (Module['elementPointerLock']) {
  4052. canvas.addEventListener("click", (ev) => {
  4053. if (!Browser.pointerLock && Module['canvas'].requestPointerLock) {
  4054. Module['canvas'].requestPointerLock();
  4055. ev.preventDefault();
  4056. }
  4057. }, false);
  4058. }
  4059. }
  4060. },
  4061. createContext(/** @type {HTMLCanvasElement} */ canvas, useWebGL, setInModule, webGLContextAttributes) {
  4062. if (useWebGL && Module.ctx && canvas == Module['canvas']) return Module.ctx; // no need to recreate GL context if it's already been created for this canvas.
  4063. var ctx;
  4064. var contextHandle;
  4065. if (useWebGL) {
  4066. // For GLES2/desktop GL compatibility, adjust a few defaults to be different to WebGL defaults, so that they align better with the desktop defaults.
  4067. var contextAttributes = {
  4068. antialias: false,
  4069. alpha: false,
  4070. majorVersion: 1,
  4071. };
  4072. if (webGLContextAttributes) {
  4073. for (var attribute in webGLContextAttributes) {
  4074. contextAttributes[attribute] = webGLContextAttributes[attribute];
  4075. }
  4076. }
  4077. // This check of existence of GL is here to satisfy Closure compiler, which yells if variable GL is referenced below but GL object is not
  4078. // actually compiled in because application is not doing any GL operations. TODO: Ideally if GL is not being used, this function
  4079. // Browser.createContext() should not even be emitted.
  4080. if (typeof GL != 'undefined') {
  4081. contextHandle = GL.createContext(canvas, contextAttributes);
  4082. if (contextHandle) {
  4083. ctx = GL.getContext(contextHandle).GLctx;
  4084. }
  4085. }
  4086. } else {
  4087. ctx = canvas.getContext('2d');
  4088. }
  4089. if (!ctx) return null;
  4090. if (setInModule) {
  4091. if (!useWebGL) assert(typeof GLctx == 'undefined', 'cannot set in module if GLctx is used, but we are a non-GL context that would replace it');
  4092. Module.ctx = ctx;
  4093. if (useWebGL) GL.makeContextCurrent(contextHandle);
  4094. Browser.useWebGL = useWebGL;
  4095. Browser.moduleContextCreatedCallbacks.forEach((callback) => callback());
  4096. Browser.init();
  4097. }
  4098. return ctx;
  4099. },
  4100. fullscreenHandlersInstalled:false,
  4101. lockPointer:undefined,
  4102. resizeCanvas:undefined,
  4103. requestFullscreen(lockPointer, resizeCanvas) {
  4104. Browser.lockPointer = lockPointer;
  4105. Browser.resizeCanvas = resizeCanvas;
  4106. if (typeof Browser.lockPointer == 'undefined') Browser.lockPointer = true;
  4107. if (typeof Browser.resizeCanvas == 'undefined') Browser.resizeCanvas = false;
  4108. var canvas = Module['canvas'];
  4109. function fullscreenChange() {
  4110. Browser.isFullscreen = false;
  4111. var canvasContainer = canvas.parentNode;
  4112. if ((document['fullscreenElement'] || document['mozFullScreenElement'] ||
  4113. document['msFullscreenElement'] || document['webkitFullscreenElement'] ||
  4114. document['webkitCurrentFullScreenElement']) === canvasContainer) {
  4115. canvas.exitFullscreen = Browser.exitFullscreen;
  4116. if (Browser.lockPointer) canvas.requestPointerLock();
  4117. Browser.isFullscreen = true;
  4118. if (Browser.resizeCanvas) {
  4119. Browser.setFullscreenCanvasSize();
  4120. } else {
  4121. Browser.updateCanvasDimensions(canvas);
  4122. }
  4123. } else {
  4124. // remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen
  4125. canvasContainer.parentNode.insertBefore(canvas, canvasContainer);
  4126. canvasContainer.parentNode.removeChild(canvasContainer);
  4127. if (Browser.resizeCanvas) {
  4128. Browser.setWindowedCanvasSize();
  4129. } else {
  4130. Browser.updateCanvasDimensions(canvas);
  4131. }
  4132. }
  4133. Module['onFullScreen']?.(Browser.isFullscreen);
  4134. Module['onFullscreen']?.(Browser.isFullscreen);
  4135. }
  4136. if (!Browser.fullscreenHandlersInstalled) {
  4137. Browser.fullscreenHandlersInstalled = true;
  4138. document.addEventListener('fullscreenchange', fullscreenChange, false);
  4139. document.addEventListener('mozfullscreenchange', fullscreenChange, false);
  4140. document.addEventListener('webkitfullscreenchange', fullscreenChange, false);
  4141. document.addEventListener('MSFullscreenChange', fullscreenChange, false);
  4142. }
  4143. // create a new parent to ensure the canvas has no siblings. this allows browsers to optimize full screen performance when its parent is the full screen root
  4144. var canvasContainer = document.createElement("div");
  4145. canvas.parentNode.insertBefore(canvasContainer, canvas);
  4146. canvasContainer.appendChild(canvas);
  4147. // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size)
  4148. canvasContainer.requestFullscreen = canvasContainer['requestFullscreen'] ||
  4149. canvasContainer['mozRequestFullScreen'] ||
  4150. canvasContainer['msRequestFullscreen'] ||
  4151. (canvasContainer['webkitRequestFullscreen'] ? () => canvasContainer['webkitRequestFullscreen'](Element['ALLOW_KEYBOARD_INPUT']) : null) ||
  4152. (canvasContainer['webkitRequestFullScreen'] ? () => canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) : null);
  4153. canvasContainer.requestFullscreen();
  4154. },
  4155. requestFullScreen() {
  4156. abort('Module.requestFullScreen has been replaced by Module.requestFullscreen (without a capital S)');
  4157. },
  4158. exitFullscreen() {
  4159. // This is workaround for chrome. Trying to exit from fullscreen
  4160. // not in fullscreen state will cause "TypeError: Document not active"
  4161. // in chrome. See https://github.com/emscripten-core/emscripten/pull/8236
  4162. if (!Browser.isFullscreen) {
  4163. return false;
  4164. }
  4165. var CFS = document['exitFullscreen'] ||
  4166. document['cancelFullScreen'] ||
  4167. document['mozCancelFullScreen'] ||
  4168. document['msExitFullscreen'] ||
  4169. document['webkitCancelFullScreen'] ||
  4170. (() => {});
  4171. CFS.apply(document, []);
  4172. return true;
  4173. },
  4174. safeSetTimeout(func, timeout) {
  4175. // Legacy function, this is used by the SDL2 port so we need to keep it
  4176. // around at least until that is updated.
  4177. // See https://github.com/libsdl-org/SDL/pull/6304
  4178. return safeSetTimeout(func, timeout);
  4179. },
  4180. getMimetype(name) {
  4181. return {
  4182. 'jpg': 'image/jpeg',
  4183. 'jpeg': 'image/jpeg',
  4184. 'png': 'image/png',
  4185. 'bmp': 'image/bmp',
  4186. 'ogg': 'audio/ogg',
  4187. 'wav': 'audio/wav',
  4188. 'mp3': 'audio/mpeg'
  4189. }[name.substr(name.lastIndexOf('.')+1)];
  4190. },
  4191. getUserMedia(func) {
  4192. window.getUserMedia ||= navigator['getUserMedia'] ||
  4193. navigator['mozGetUserMedia'];
  4194. window.getUserMedia(func);
  4195. },
  4196. getMovementX(event) {
  4197. return event['movementX'] ||
  4198. event['mozMovementX'] ||
  4199. event['webkitMovementX'] ||
  4200. 0;
  4201. },
  4202. getMovementY(event) {
  4203. return event['movementY'] ||
  4204. event['mozMovementY'] ||
  4205. event['webkitMovementY'] ||
  4206. 0;
  4207. },
  4208. getMouseWheelDelta(event) {
  4209. var delta = 0;
  4210. switch (event.type) {
  4211. case 'DOMMouseScroll':
  4212. // 3 lines make up a step
  4213. delta = event.detail / 3;
  4214. break;
  4215. case 'mousewheel':
  4216. // 120 units make up a step
  4217. delta = event.wheelDelta / 120;
  4218. break;
  4219. case 'wheel':
  4220. delta = event.deltaY
  4221. switch (event.deltaMode) {
  4222. case 0:
  4223. // DOM_DELTA_PIXEL: 100 pixels make up a step
  4224. delta /= 100;
  4225. break;
  4226. case 1:
  4227. // DOM_DELTA_LINE: 3 lines make up a step
  4228. delta /= 3;
  4229. break;
  4230. case 2:
  4231. // DOM_DELTA_PAGE: A page makes up 80 steps
  4232. delta *= 80;
  4233. break;
  4234. default:
  4235. throw 'unrecognized mouse wheel delta mode: ' + event.deltaMode;
  4236. }
  4237. break;
  4238. default:
  4239. throw 'unrecognized mouse wheel event: ' + event.type;
  4240. }
  4241. return delta;
  4242. },
  4243. mouseX:0,
  4244. mouseY:0,
  4245. mouseMovementX:0,
  4246. mouseMovementY:0,
  4247. touches:{
  4248. },
  4249. lastTouches:{
  4250. },
  4251. calculateMouseCoords(pageX, pageY) {
  4252. // Calculate the movement based on the changes
  4253. // in the coordinates.
  4254. var rect = Module["canvas"].getBoundingClientRect();
  4255. var cw = Module["canvas"].width;
  4256. var ch = Module["canvas"].height;
  4257. // Neither .scrollX or .pageXOffset are defined in a spec, but
  4258. // we prefer .scrollX because it is currently in a spec draft.
  4259. // (see: http://www.w3.org/TR/2013/WD-cssom-view-20131217/)
  4260. var scrollX = ((typeof window.scrollX != 'undefined') ? window.scrollX : window.pageXOffset);
  4261. var scrollY = ((typeof window.scrollY != 'undefined') ? window.scrollY : window.pageYOffset);
  4262. // If this assert lands, it's likely because the browser doesn't support scrollX or pageXOffset
  4263. // and we have no viable fallback.
  4264. assert((typeof scrollX != 'undefined') && (typeof scrollY != 'undefined'), 'Unable to retrieve scroll position, mouse positions likely broken.');
  4265. var adjustedX = pageX - (scrollX + rect.left);
  4266. var adjustedY = pageY - (scrollY + rect.top);
  4267. // the canvas might be CSS-scaled compared to its backbuffer;
  4268. // SDL-using content will want mouse coordinates in terms
  4269. // of backbuffer units.
  4270. adjustedX = adjustedX * (cw / rect.width);
  4271. adjustedY = adjustedY * (ch / rect.height);
  4272. return { x: adjustedX, y: adjustedY };
  4273. },
  4274. setMouseCoords(pageX, pageY) {
  4275. const {x, y} = Browser.calculateMouseCoords(pageX, pageY);
  4276. Browser.mouseMovementX = x - Browser.mouseX;
  4277. Browser.mouseMovementY = y - Browser.mouseY;
  4278. Browser.mouseX = x;
  4279. Browser.mouseY = y;
  4280. },
  4281. calculateMouseEvent(event) { // event should be mousemove, mousedown or mouseup
  4282. if (Browser.pointerLock) {
  4283. // When the pointer is locked, calculate the coordinates
  4284. // based on the movement of the mouse.
  4285. // Workaround for Firefox bug 764498
  4286. if (event.type != 'mousemove' &&
  4287. ('mozMovementX' in event)) {
  4288. Browser.mouseMovementX = Browser.mouseMovementY = 0;
  4289. } else {
  4290. Browser.mouseMovementX = Browser.getMovementX(event);
  4291. Browser.mouseMovementY = Browser.getMovementY(event);
  4292. }
  4293. // add the mouse delta to the current absolute mouse position
  4294. Browser.mouseX += Browser.mouseMovementX;
  4295. Browser.mouseY += Browser.mouseMovementY;
  4296. } else {
  4297. if (event.type === 'touchstart' || event.type === 'touchend' || event.type === 'touchmove') {
  4298. var touch = event.touch;
  4299. if (touch === undefined) {
  4300. return; // the "touch" property is only defined in SDL
  4301. }
  4302. var coords = Browser.calculateMouseCoords(touch.pageX, touch.pageY);
  4303. if (event.type === 'touchstart') {
  4304. Browser.lastTouches[touch.identifier] = coords;
  4305. Browser.touches[touch.identifier] = coords;
  4306. } else if (event.type === 'touchend' || event.type === 'touchmove') {
  4307. var last = Browser.touches[touch.identifier];
  4308. last ||= coords;
  4309. Browser.lastTouches[touch.identifier] = last;
  4310. Browser.touches[touch.identifier] = coords;
  4311. }
  4312. return;
  4313. }
  4314. Browser.setMouseCoords(event.pageX, event.pageY);
  4315. }
  4316. },
  4317. resizeListeners:[],
  4318. updateResizeListeners() {
  4319. var canvas = Module['canvas'];
  4320. Browser.resizeListeners.forEach((listener) => listener(canvas.width, canvas.height));
  4321. },
  4322. setCanvasSize(width, height, noUpdates) {
  4323. var canvas = Module['canvas'];
  4324. Browser.updateCanvasDimensions(canvas, width, height);
  4325. if (!noUpdates) Browser.updateResizeListeners();
  4326. },
  4327. windowedWidth:0,
  4328. windowedHeight:0,
  4329. setFullscreenCanvasSize() {
  4330. // check if SDL is available
  4331. if (typeof SDL != "undefined") {
  4332. var flags = HEAPU32[((SDL.screen)>>2)];
  4333. flags = flags | 0x00800000; // set SDL_FULLSCREEN flag
  4334. HEAP32[((SDL.screen)>>2)] = flags;
  4335. }
  4336. Browser.updateCanvasDimensions(Module['canvas']);
  4337. Browser.updateResizeListeners();
  4338. },
  4339. setWindowedCanvasSize() {
  4340. // check if SDL is available
  4341. if (typeof SDL != "undefined") {
  4342. var flags = HEAPU32[((SDL.screen)>>2)];
  4343. flags = flags & ~0x00800000; // clear SDL_FULLSCREEN flag
  4344. HEAP32[((SDL.screen)>>2)] = flags;
  4345. }
  4346. Browser.updateCanvasDimensions(Module['canvas']);
  4347. Browser.updateResizeListeners();
  4348. },
  4349. updateCanvasDimensions(canvas, wNative, hNative) {
  4350. if (wNative && hNative) {
  4351. canvas.widthNative = wNative;
  4352. canvas.heightNative = hNative;
  4353. } else {
  4354. wNative = canvas.widthNative;
  4355. hNative = canvas.heightNative;
  4356. }
  4357. var w = wNative;
  4358. var h = hNative;
  4359. if (Module['forcedAspectRatio'] && Module['forcedAspectRatio'] > 0) {
  4360. if (w/h < Module['forcedAspectRatio']) {
  4361. w = Math.round(h * Module['forcedAspectRatio']);
  4362. } else {
  4363. h = Math.round(w / Module['forcedAspectRatio']);
  4364. }
  4365. }
  4366. if (((document['fullscreenElement'] || document['mozFullScreenElement'] ||
  4367. document['msFullscreenElement'] || document['webkitFullscreenElement'] ||
  4368. document['webkitCurrentFullScreenElement']) === canvas.parentNode) && (typeof screen != 'undefined')) {
  4369. var factor = Math.min(screen.width / w, screen.height / h);
  4370. w = Math.round(w * factor);
  4371. h = Math.round(h * factor);
  4372. }
  4373. if (Browser.resizeCanvas) {
  4374. if (canvas.width != w) canvas.width = w;
  4375. if (canvas.height != h) canvas.height = h;
  4376. if (typeof canvas.style != 'undefined') {
  4377. canvas.style.removeProperty( "width");
  4378. canvas.style.removeProperty("height");
  4379. }
  4380. } else {
  4381. if (canvas.width != wNative) canvas.width = wNative;
  4382. if (canvas.height != hNative) canvas.height = hNative;
  4383. if (typeof canvas.style != 'undefined') {
  4384. if (w != wNative || h != hNative) {
  4385. canvas.style.setProperty( "width", w + "px", "important");
  4386. canvas.style.setProperty("height", h + "px", "important");
  4387. } else {
  4388. canvas.style.removeProperty( "width");
  4389. canvas.style.removeProperty("height");
  4390. }
  4391. }
  4392. }
  4393. },
  4394. };
  4395. var EGL = {
  4396. errorCode:12288,
  4397. defaultDisplayInitialized:false,
  4398. currentContext:0,
  4399. currentReadSurface:0,
  4400. currentDrawSurface:0,
  4401. contextAttributes:{
  4402. alpha:false,
  4403. depth:false,
  4404. stencil:false,
  4405. antialias:false,
  4406. },
  4407. stringCache:{
  4408. },
  4409. setErrorCode(code) {
  4410. EGL.errorCode = code;
  4411. },
  4412. chooseConfig(display, attribList, config, config_size, numConfigs) {
  4413. if (display != 62000) {
  4414. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  4415. return 0;
  4416. }
  4417. if (attribList) {
  4418. // read attribList if it is non-null
  4419. for (;;) {
  4420. var param = HEAP32[((attribList)>>2)];
  4421. if (param == 0x3021 /*EGL_ALPHA_SIZE*/) {
  4422. var alphaSize = HEAP32[(((attribList)+(4))>>2)];
  4423. EGL.contextAttributes.alpha = (alphaSize > 0);
  4424. } else if (param == 0x3025 /*EGL_DEPTH_SIZE*/) {
  4425. var depthSize = HEAP32[(((attribList)+(4))>>2)];
  4426. EGL.contextAttributes.depth = (depthSize > 0);
  4427. } else if (param == 0x3026 /*EGL_STENCIL_SIZE*/) {
  4428. var stencilSize = HEAP32[(((attribList)+(4))>>2)];
  4429. EGL.contextAttributes.stencil = (stencilSize > 0);
  4430. } else if (param == 0x3031 /*EGL_SAMPLES*/) {
  4431. var samples = HEAP32[(((attribList)+(4))>>2)];
  4432. EGL.contextAttributes.antialias = (samples > 0);
  4433. } else if (param == 0x3032 /*EGL_SAMPLE_BUFFERS*/) {
  4434. var samples = HEAP32[(((attribList)+(4))>>2)];
  4435. EGL.contextAttributes.antialias = (samples == 1);
  4436. } else if (param == 0x3100 /*EGL_CONTEXT_PRIORITY_LEVEL_IMG*/) {
  4437. var requestedPriority = HEAP32[(((attribList)+(4))>>2)];
  4438. EGL.contextAttributes.lowLatency = (requestedPriority != 0x3103 /*EGL_CONTEXT_PRIORITY_LOW_IMG*/);
  4439. } else if (param == 0x3038 /*EGL_NONE*/) {
  4440. break;
  4441. }
  4442. attribList += 8;
  4443. }
  4444. }
  4445. if ((!config || !config_size) && !numConfigs) {
  4446. EGL.setErrorCode(0x300C /* EGL_BAD_PARAMETER */);
  4447. return 0;
  4448. }
  4449. if (numConfigs) {
  4450. HEAP32[((numConfigs)>>2)] = 1; // Total number of supported configs: 1.
  4451. }
  4452. if (config && config_size > 0) {
  4453. HEAPU32[((config)>>2)] = 62002;
  4454. }
  4455. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4456. return 1;
  4457. },
  4458. };
  4459. var _eglBindAPI = (api) => {
  4460. if (api == 0x30A0 /* EGL_OPENGL_ES_API */) {
  4461. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4462. return 1;
  4463. }
  4464. // if (api == 0x30A1 /* EGL_OPENVG_API */ || api == 0x30A2 /* EGL_OPENGL_API */) {
  4465. EGL.setErrorCode(0x300C /* EGL_BAD_PARAMETER */);
  4466. return 0;
  4467. };
  4468. var _eglChooseConfig = (display, attrib_list, configs, config_size, numConfigs) => {
  4469. return EGL.chooseConfig(display, attrib_list, configs, config_size, numConfigs);
  4470. };
  4471. var GLctx;
  4472. var webgl_enable_ANGLE_instanced_arrays = (ctx) => {
  4473. // Extension available in WebGL 1 from Firefox 26 and Google Chrome 30 onwards. Core feature in WebGL 2.
  4474. var ext = ctx.getExtension('ANGLE_instanced_arrays');
  4475. // Because this extension is a core function in WebGL 2, assign the extension entry points in place of
  4476. // where the core functions will reside in WebGL 2. This way the calling code can call these without
  4477. // having to dynamically branch depending if running against WebGL 1 or WebGL 2.
  4478. if (ext) {
  4479. ctx['vertexAttribDivisor'] = (index, divisor) => ext['vertexAttribDivisorANGLE'](index, divisor);
  4480. ctx['drawArraysInstanced'] = (mode, first, count, primcount) => ext['drawArraysInstancedANGLE'](mode, first, count, primcount);
  4481. ctx['drawElementsInstanced'] = (mode, count, type, indices, primcount) => ext['drawElementsInstancedANGLE'](mode, count, type, indices, primcount);
  4482. return 1;
  4483. }
  4484. };
  4485. var webgl_enable_OES_vertex_array_object = (ctx) => {
  4486. // Extension available in WebGL 1 from Firefox 25 and WebKit 536.28/desktop Safari 6.0.3 onwards. Core feature in WebGL 2.
  4487. var ext = ctx.getExtension('OES_vertex_array_object');
  4488. if (ext) {
  4489. ctx['createVertexArray'] = () => ext['createVertexArrayOES']();
  4490. ctx['deleteVertexArray'] = (vao) => ext['deleteVertexArrayOES'](vao);
  4491. ctx['bindVertexArray'] = (vao) => ext['bindVertexArrayOES'](vao);
  4492. ctx['isVertexArray'] = (vao) => ext['isVertexArrayOES'](vao);
  4493. return 1;
  4494. }
  4495. };
  4496. var webgl_enable_WEBGL_draw_buffers = (ctx) => {
  4497. // Extension available in WebGL 1 from Firefox 28 onwards. Core feature in WebGL 2.
  4498. var ext = ctx.getExtension('WEBGL_draw_buffers');
  4499. if (ext) {
  4500. ctx['drawBuffers'] = (n, bufs) => ext['drawBuffersWEBGL'](n, bufs);
  4501. return 1;
  4502. }
  4503. };
  4504. var webgl_enable_EXT_polygon_offset_clamp = (ctx) => {
  4505. return !!(ctx.extPolygonOffsetClamp = ctx.getExtension('EXT_polygon_offset_clamp'));
  4506. };
  4507. var webgl_enable_EXT_clip_control = (ctx) => {
  4508. return !!(ctx.extClipControl = ctx.getExtension('EXT_clip_control'));
  4509. };
  4510. var webgl_enable_WEBGL_polygon_mode = (ctx) => {
  4511. return !!(ctx.webglPolygonMode = ctx.getExtension('WEBGL_polygon_mode'));
  4512. };
  4513. var webgl_enable_WEBGL_multi_draw = (ctx) => {
  4514. // Closure is expected to be allowed to minify the '.multiDrawWebgl' property, so not accessing it quoted.
  4515. return !!(ctx.multiDrawWebgl = ctx.getExtension('WEBGL_multi_draw'));
  4516. };
  4517. var getEmscriptenSupportedExtensions = (ctx) => {
  4518. // Restrict the list of advertised extensions to those that we actually
  4519. // support.
  4520. var supportedExtensions = [
  4521. // WebGL 1 extensions
  4522. 'ANGLE_instanced_arrays',
  4523. 'EXT_blend_minmax',
  4524. 'EXT_disjoint_timer_query',
  4525. 'EXT_frag_depth',
  4526. 'EXT_shader_texture_lod',
  4527. 'EXT_sRGB',
  4528. 'OES_element_index_uint',
  4529. 'OES_fbo_render_mipmap',
  4530. 'OES_standard_derivatives',
  4531. 'OES_texture_float',
  4532. 'OES_texture_half_float',
  4533. 'OES_texture_half_float_linear',
  4534. 'OES_vertex_array_object',
  4535. 'WEBGL_color_buffer_float',
  4536. 'WEBGL_depth_texture',
  4537. 'WEBGL_draw_buffers',
  4538. // WebGL 1 and WebGL 2 extensions
  4539. 'EXT_clip_control',
  4540. 'EXT_color_buffer_half_float',
  4541. 'EXT_depth_clamp',
  4542. 'EXT_float_blend',
  4543. 'EXT_polygon_offset_clamp',
  4544. 'EXT_texture_compression_bptc',
  4545. 'EXT_texture_compression_rgtc',
  4546. 'EXT_texture_filter_anisotropic',
  4547. 'KHR_parallel_shader_compile',
  4548. 'OES_texture_float_linear',
  4549. 'WEBGL_blend_func_extended',
  4550. 'WEBGL_compressed_texture_astc',
  4551. 'WEBGL_compressed_texture_etc',
  4552. 'WEBGL_compressed_texture_etc1',
  4553. 'WEBGL_compressed_texture_s3tc',
  4554. 'WEBGL_compressed_texture_s3tc_srgb',
  4555. 'WEBGL_debug_renderer_info',
  4556. 'WEBGL_debug_shaders',
  4557. 'WEBGL_lose_context',
  4558. 'WEBGL_multi_draw',
  4559. 'WEBGL_polygon_mode'
  4560. ];
  4561. // .getSupportedExtensions() can return null if context is lost, so coerce to empty array.
  4562. return (ctx.getSupportedExtensions() || []).filter(ext => supportedExtensions.includes(ext));
  4563. };
  4564. var GL = {
  4565. counter:1,
  4566. buffers:[],
  4567. programs:[],
  4568. framebuffers:[],
  4569. renderbuffers:[],
  4570. textures:[],
  4571. shaders:[],
  4572. vaos:[],
  4573. contexts:[],
  4574. offscreenCanvases:{
  4575. },
  4576. queries:[],
  4577. stringCache:{
  4578. },
  4579. unpackAlignment:4,
  4580. unpackRowLength:0,
  4581. recordError:(errorCode) => {
  4582. if (!GL.lastError) {
  4583. GL.lastError = errorCode;
  4584. }
  4585. },
  4586. getNewId:(table) => {
  4587. var ret = GL.counter++;
  4588. for (var i = table.length; i < ret; i++) {
  4589. table[i] = null;
  4590. }
  4591. return ret;
  4592. },
  4593. genObject:(n, buffers, createFunction, objectTable
  4594. ) => {
  4595. for (var i = 0; i < n; i++) {
  4596. var buffer = GLctx[createFunction]();
  4597. var id = buffer && GL.getNewId(objectTable);
  4598. if (buffer) {
  4599. buffer.name = id;
  4600. objectTable[id] = buffer;
  4601. } else {
  4602. GL.recordError(0x502 /* GL_INVALID_OPERATION */);
  4603. }
  4604. HEAP32[(((buffers)+(i*4))>>2)] = id;
  4605. }
  4606. },
  4607. getSource:(shader, count, string, length) => {
  4608. var source = '';
  4609. for (var i = 0; i < count; ++i) {
  4610. var len = length ? HEAPU32[(((length)+(i*4))>>2)] : undefined;
  4611. source += UTF8ToString(HEAPU32[(((string)+(i*4))>>2)], len);
  4612. }
  4613. return source;
  4614. },
  4615. createContext:(/** @type {HTMLCanvasElement} */ canvas, webGLContextAttributes) => {
  4616. // BUG: Workaround Safari WebGL issue: After successfully acquiring WebGL
  4617. // context on a canvas, calling .getContext() will always return that
  4618. // context independent of which 'webgl' or 'webgl2'
  4619. // context version was passed. See:
  4620. // https://bugs.webkit.org/show_bug.cgi?id=222758
  4621. // and:
  4622. // https://github.com/emscripten-core/emscripten/issues/13295.
  4623. // TODO: Once the bug is fixed and shipped in Safari, adjust the Safari
  4624. // version field in above check.
  4625. if (!canvas.getContextSafariWebGL2Fixed) {
  4626. canvas.getContextSafariWebGL2Fixed = canvas.getContext;
  4627. /** @type {function(this:HTMLCanvasElement, string, (Object|null)=): (Object|null)} */
  4628. function fixedGetContext(ver, attrs) {
  4629. var gl = canvas.getContextSafariWebGL2Fixed(ver, attrs);
  4630. return ((ver == 'webgl') == (gl instanceof WebGLRenderingContext)) ? gl : null;
  4631. }
  4632. canvas.getContext = fixedGetContext;
  4633. }
  4634. var ctx =
  4635. (canvas.getContext("webgl", webGLContextAttributes)
  4636. // https://caniuse.com/#feat=webgl
  4637. );
  4638. if (!ctx) return 0;
  4639. var handle = GL.registerContext(ctx, webGLContextAttributes);
  4640. return handle;
  4641. },
  4642. registerContext:(ctx, webGLContextAttributes) => {
  4643. // without pthreads a context is just an integer ID
  4644. var handle = GL.getNewId(GL.contexts);
  4645. var context = {
  4646. handle,
  4647. attributes: webGLContextAttributes,
  4648. version: webGLContextAttributes.majorVersion,
  4649. GLctx: ctx
  4650. };
  4651. // Store the created context object so that we can access the context
  4652. // given a canvas without having to pass the parameters again.
  4653. if (ctx.canvas) ctx.canvas.GLctxObject = context;
  4654. GL.contexts[handle] = context;
  4655. if (typeof webGLContextAttributes.enableExtensionsByDefault == 'undefined' || webGLContextAttributes.enableExtensionsByDefault) {
  4656. GL.initExtensions(context);
  4657. }
  4658. return handle;
  4659. },
  4660. makeContextCurrent:(contextHandle) => {
  4661. // Active Emscripten GL layer context object.
  4662. GL.currentContext = GL.contexts[contextHandle];
  4663. // Active WebGL context object.
  4664. Module.ctx = GLctx = GL.currentContext?.GLctx;
  4665. return !(contextHandle && !GLctx);
  4666. },
  4667. getContext:(contextHandle) => {
  4668. return GL.contexts[contextHandle];
  4669. },
  4670. deleteContext:(contextHandle) => {
  4671. if (GL.currentContext === GL.contexts[contextHandle]) {
  4672. GL.currentContext = null;
  4673. }
  4674. if (typeof JSEvents == 'object') {
  4675. // Release all JS event handlers on the DOM element that the GL context is
  4676. // associated with since the context is now deleted.
  4677. JSEvents.removeAllHandlersOnTarget(GL.contexts[contextHandle].GLctx.canvas);
  4678. }
  4679. // Make sure the canvas object no longer refers to the context object so
  4680. // there are no GC surprises.
  4681. if (GL.contexts[contextHandle] && GL.contexts[contextHandle].GLctx.canvas) {
  4682. GL.contexts[contextHandle].GLctx.canvas.GLctxObject = undefined;
  4683. }
  4684. GL.contexts[contextHandle] = null;
  4685. },
  4686. initExtensions:(context) => {
  4687. // If this function is called without a specific context object, init the
  4688. // extensions of the currently active context.
  4689. context ||= GL.currentContext;
  4690. if (context.initExtensionsDone) return;
  4691. context.initExtensionsDone = true;
  4692. var GLctx = context.GLctx;
  4693. // Detect the presence of a few extensions manually, ction GL interop
  4694. // layer itself will need to know if they exist.
  4695. // Extensions that are available in both WebGL 1 and WebGL 2
  4696. webgl_enable_WEBGL_multi_draw(GLctx);
  4697. webgl_enable_EXT_polygon_offset_clamp(GLctx);
  4698. webgl_enable_EXT_clip_control(GLctx);
  4699. webgl_enable_WEBGL_polygon_mode(GLctx);
  4700. // Extensions that are only available in WebGL 1 (the calls will be no-ops
  4701. // if called on a WebGL 2 context active)
  4702. webgl_enable_ANGLE_instanced_arrays(GLctx);
  4703. webgl_enable_OES_vertex_array_object(GLctx);
  4704. webgl_enable_WEBGL_draw_buffers(GLctx);
  4705. {
  4706. GLctx.disjointTimerQueryExt = GLctx.getExtension("EXT_disjoint_timer_query");
  4707. }
  4708. getEmscriptenSupportedExtensions(GLctx).forEach((ext) => {
  4709. // WEBGL_lose_context, WEBGL_debug_renderer_info and WEBGL_debug_shaders
  4710. // are not enabled by default.
  4711. if (!ext.includes('lose_context') && !ext.includes('debug')) {
  4712. // Call .getExtension() to enable that extension permanently.
  4713. GLctx.getExtension(ext);
  4714. }
  4715. });
  4716. },
  4717. };
  4718. var _eglCreateContext = (display, config, hmm, contextAttribs) => {
  4719. if (display != 62000) {
  4720. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  4721. return 0;
  4722. }
  4723. // EGL 1.4 spec says default EGL_CONTEXT_CLIENT_VERSION is GLES1, but this is not supported by Emscripten.
  4724. // So user must pass EGL_CONTEXT_CLIENT_VERSION == 2 to initialize EGL.
  4725. var glesContextVersion = 1;
  4726. for (;;) {
  4727. var param = HEAP32[((contextAttribs)>>2)];
  4728. if (param == 0x3098 /*EGL_CONTEXT_CLIENT_VERSION*/) {
  4729. glesContextVersion = HEAP32[(((contextAttribs)+(4))>>2)];
  4730. } else if (param == 0x3038 /*EGL_NONE*/) {
  4731. break;
  4732. } else {
  4733. /* EGL1.4 specifies only EGL_CONTEXT_CLIENT_VERSION as supported attribute */
  4734. EGL.setErrorCode(0x3004 /*EGL_BAD_ATTRIBUTE*/);
  4735. return 0;
  4736. }
  4737. contextAttribs += 8;
  4738. }
  4739. if (glesContextVersion != 2) {
  4740. EGL.setErrorCode(0x3005 /* EGL_BAD_CONFIG */);
  4741. return 0; /* EGL_NO_CONTEXT */
  4742. }
  4743. EGL.contextAttributes.majorVersion = glesContextVersion - 1; // WebGL 1 is GLES 2, WebGL2 is GLES3
  4744. EGL.contextAttributes.minorVersion = 0;
  4745. EGL.context = GL.createContext(Module['canvas'], EGL.contextAttributes);
  4746. if (EGL.context != 0) {
  4747. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4748. // Run callbacks so that GL emulation works
  4749. GL.makeContextCurrent(EGL.context);
  4750. Browser.useWebGL = true;
  4751. Browser.moduleContextCreatedCallbacks.forEach((callback) => callback());
  4752. // Note: This function only creates a context, but it shall not make it active.
  4753. GL.makeContextCurrent(null);
  4754. return 62004;
  4755. } else {
  4756. EGL.setErrorCode(0x3009 /* EGL_BAD_MATCH */); // By the EGL 1.4 spec, an implementation that does not support GLES2 (WebGL in this case), this error code is set.
  4757. return 0; /* EGL_NO_CONTEXT */
  4758. }
  4759. };
  4760. var _eglCreateWindowSurface = (display, config, win, attrib_list) => {
  4761. if (display != 62000) {
  4762. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  4763. return 0;
  4764. }
  4765. if (config != 62002) {
  4766. EGL.setErrorCode(0x3005 /* EGL_BAD_CONFIG */);
  4767. return 0;
  4768. }
  4769. // TODO: Examine attrib_list! Parameters that can be present there are:
  4770. // - EGL_RENDER_BUFFER (must be EGL_BACK_BUFFER)
  4771. // - EGL_VG_COLORSPACE (can't be set)
  4772. // - EGL_VG_ALPHA_FORMAT (can't be set)
  4773. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4774. return 62006; /* Magic ID for Emscripten 'default surface' */
  4775. };
  4776. var _eglDestroyContext = (display, context) => {
  4777. if (display != 62000) {
  4778. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  4779. return 0;
  4780. }
  4781. if (context != 62004) {
  4782. EGL.setErrorCode(0x3006 /* EGL_BAD_CONTEXT */);
  4783. return 0;
  4784. }
  4785. GL.deleteContext(EGL.context);
  4786. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4787. if (EGL.currentContext == context) {
  4788. EGL.currentContext = 0;
  4789. }
  4790. return 1 /* EGL_TRUE */;
  4791. };
  4792. var _eglDestroySurface = (display, surface) => {
  4793. if (display != 62000) {
  4794. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  4795. return 0;
  4796. }
  4797. if (surface != 62006 /* Magic ID for the only EGLSurface supported by Emscripten */) {
  4798. EGL.setErrorCode(0x300D /* EGL_BAD_SURFACE */);
  4799. return 1;
  4800. }
  4801. if (EGL.currentReadSurface == surface) {
  4802. EGL.currentReadSurface = 0;
  4803. }
  4804. if (EGL.currentDrawSurface == surface) {
  4805. EGL.currentDrawSurface = 0;
  4806. }
  4807. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4808. return 1; /* Magic ID for Emscripten 'default surface' */
  4809. };
  4810. var _eglGetConfigAttrib = (display, config, attribute, value) => {
  4811. if (display != 62000) {
  4812. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  4813. return 0;
  4814. }
  4815. if (config != 62002) {
  4816. EGL.setErrorCode(0x3005 /* EGL_BAD_CONFIG */);
  4817. return 0;
  4818. }
  4819. if (!value) {
  4820. EGL.setErrorCode(0x300C /* EGL_BAD_PARAMETER */);
  4821. return 0;
  4822. }
  4823. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4824. switch (attribute) {
  4825. case 0x3020: // EGL_BUFFER_SIZE
  4826. HEAP32[((value)>>2)] = EGL.contextAttributes.alpha ? 32 : 24;
  4827. return 1;
  4828. case 0x3021: // EGL_ALPHA_SIZE
  4829. HEAP32[((value)>>2)] = EGL.contextAttributes.alpha ? 8 : 0;
  4830. return 1;
  4831. case 0x3022: // EGL_BLUE_SIZE
  4832. HEAP32[((value)>>2)] = 8;
  4833. return 1;
  4834. case 0x3023: // EGL_GREEN_SIZE
  4835. HEAP32[((value)>>2)] = 8;
  4836. return 1;
  4837. case 0x3024: // EGL_RED_SIZE
  4838. HEAP32[((value)>>2)] = 8;
  4839. return 1;
  4840. case 0x3025: // EGL_DEPTH_SIZE
  4841. HEAP32[((value)>>2)] = EGL.contextAttributes.depth ? 24 : 0;
  4842. return 1;
  4843. case 0x3026: // EGL_STENCIL_SIZE
  4844. HEAP32[((value)>>2)] = EGL.contextAttributes.stencil ? 8 : 0;
  4845. return 1;
  4846. case 0x3027: // EGL_CONFIG_CAVEAT
  4847. // We can return here one of EGL_NONE (0x3038), EGL_SLOW_CONFIG (0x3050) or EGL_NON_CONFORMANT_CONFIG (0x3051).
  4848. HEAP32[((value)>>2)] = 0x3038;
  4849. return 1;
  4850. case 0x3028: // EGL_CONFIG_ID
  4851. HEAP32[((value)>>2)] = 62002;
  4852. return 1;
  4853. case 0x3029: // EGL_LEVEL
  4854. HEAP32[((value)>>2)] = 0;
  4855. return 1;
  4856. case 0x302A: // EGL_MAX_PBUFFER_HEIGHT
  4857. HEAP32[((value)>>2)] = 4096;
  4858. return 1;
  4859. case 0x302B: // EGL_MAX_PBUFFER_PIXELS
  4860. HEAP32[((value)>>2)] = 16777216;
  4861. return 1;
  4862. case 0x302C: // EGL_MAX_PBUFFER_WIDTH
  4863. HEAP32[((value)>>2)] = 4096;
  4864. return 1;
  4865. case 0x302D: // EGL_NATIVE_RENDERABLE
  4866. HEAP32[((value)>>2)] = 0;
  4867. return 1;
  4868. case 0x302E: // EGL_NATIVE_VISUAL_ID
  4869. HEAP32[((value)>>2)] = 0;
  4870. return 1;
  4871. case 0x302F: // EGL_NATIVE_VISUAL_TYPE
  4872. HEAP32[((value)>>2)] = 0x3038;
  4873. return 1;
  4874. case 0x3031: // EGL_SAMPLES
  4875. HEAP32[((value)>>2)] = EGL.contextAttributes.antialias ? 4 : 0;
  4876. return 1;
  4877. case 0x3032: // EGL_SAMPLE_BUFFERS
  4878. HEAP32[((value)>>2)] = EGL.contextAttributes.antialias ? 1 : 0;
  4879. return 1;
  4880. case 0x3033: // EGL_SURFACE_TYPE
  4881. HEAP32[((value)>>2)] = 0x4;
  4882. return 1;
  4883. case 0x3034: // EGL_TRANSPARENT_TYPE
  4884. // If this returns EGL_TRANSPARENT_RGB (0x3052), transparency is used through color-keying. No such thing applies to Emscripten canvas.
  4885. HEAP32[((value)>>2)] = 0x3038;
  4886. return 1;
  4887. case 0x3035: // EGL_TRANSPARENT_BLUE_VALUE
  4888. case 0x3036: // EGL_TRANSPARENT_GREEN_VALUE
  4889. case 0x3037: // EGL_TRANSPARENT_RED_VALUE
  4890. // "If EGL_TRANSPARENT_TYPE is EGL_NONE, then the values for EGL_TRANSPARENT_RED_VALUE, EGL_TRANSPARENT_GREEN_VALUE, and EGL_TRANSPARENT_BLUE_VALUE are undefined."
  4891. HEAP32[((value)>>2)] = -1;
  4892. return 1;
  4893. case 0x3039: // EGL_BIND_TO_TEXTURE_RGB
  4894. case 0x303A: // EGL_BIND_TO_TEXTURE_RGBA
  4895. HEAP32[((value)>>2)] = 0;
  4896. return 1;
  4897. case 0x303B: // EGL_MIN_SWAP_INTERVAL
  4898. HEAP32[((value)>>2)] = 0;
  4899. return 1;
  4900. case 0x303C: // EGL_MAX_SWAP_INTERVAL
  4901. HEAP32[((value)>>2)] = 1;
  4902. return 1;
  4903. case 0x303D: // EGL_LUMINANCE_SIZE
  4904. case 0x303E: // EGL_ALPHA_MASK_SIZE
  4905. HEAP32[((value)>>2)] = 0;
  4906. return 1;
  4907. case 0x303F: // EGL_COLOR_BUFFER_TYPE
  4908. // EGL has two types of buffers: EGL_RGB_BUFFER and EGL_LUMINANCE_BUFFER.
  4909. HEAP32[((value)>>2)] = 0x308E;
  4910. return 1;
  4911. case 0x3040: // EGL_RENDERABLE_TYPE
  4912. // A bit combination of EGL_OPENGL_ES_BIT,EGL_OPENVG_BIT,EGL_OPENGL_ES2_BIT and EGL_OPENGL_BIT.
  4913. HEAP32[((value)>>2)] = 0x4;
  4914. return 1;
  4915. case 0x3042: // EGL_CONFORMANT
  4916. // "EGL_CONFORMANT is a mask indicating if a client API context created with respect to the corresponding EGLConfig will pass the required conformance tests for that API."
  4917. HEAP32[((value)>>2)] = 0;
  4918. return 1;
  4919. default:
  4920. EGL.setErrorCode(0x3004 /* EGL_BAD_ATTRIBUTE */);
  4921. return 0;
  4922. }
  4923. };
  4924. var _eglGetDisplay = (nativeDisplayType) => {
  4925. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4926. // Emscripten EGL implementation "emulates" X11, and eglGetDisplay is
  4927. // expected to accept/receive a pointer to an X11 Display object (or
  4928. // EGL_DEFAULT_DISPLAY).
  4929. if (nativeDisplayType != 0 /* EGL_DEFAULT_DISPLAY */ && nativeDisplayType != 1 /* see library_xlib.js */) {
  4930. return 0; // EGL_NO_DISPLAY
  4931. }
  4932. return 62000;
  4933. };
  4934. var _eglGetError = () => EGL.errorCode;
  4935. var _eglInitialize = (display, majorVersion, minorVersion) => {
  4936. if (display != 62000) {
  4937. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  4938. return 0;
  4939. }
  4940. if (majorVersion) {
  4941. HEAP32[((majorVersion)>>2)] = 1; // Advertise EGL Major version: '1'
  4942. }
  4943. if (minorVersion) {
  4944. HEAP32[((minorVersion)>>2)] = 4; // Advertise EGL Minor version: '4'
  4945. }
  4946. EGL.defaultDisplayInitialized = true;
  4947. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4948. return 1;
  4949. };
  4950. var _eglMakeCurrent = (display, draw, read, context) => {
  4951. if (display != 62000) {
  4952. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  4953. return 0 /* EGL_FALSE */;
  4954. }
  4955. //\todo An EGL_NOT_INITIALIZED error is generated if EGL is not initialized for dpy.
  4956. if (context != 0 && context != 62004) {
  4957. EGL.setErrorCode(0x3006 /* EGL_BAD_CONTEXT */);
  4958. return 0;
  4959. }
  4960. if ((read != 0 && read != 62006) || (draw != 0 && draw != 62006 /* Magic ID for Emscripten 'default surface' */)) {
  4961. EGL.setErrorCode(0x300D /* EGL_BAD_SURFACE */);
  4962. return 0;
  4963. }
  4964. GL.makeContextCurrent(context ? EGL.context : null);
  4965. EGL.currentContext = context;
  4966. EGL.currentDrawSurface = draw;
  4967. EGL.currentReadSurface = read;
  4968. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4969. return 1 /* EGL_TRUE */;
  4970. };
  4971. var stringToNewUTF8 = (str) => {
  4972. var size = lengthBytesUTF8(str) + 1;
  4973. var ret = _malloc(size);
  4974. if (ret) stringToUTF8(str, ret, size);
  4975. return ret;
  4976. };
  4977. var _eglQueryString = (display, name) => {
  4978. if (display != 62000) {
  4979. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  4980. return 0;
  4981. }
  4982. //\todo An EGL_NOT_INITIALIZED error is generated if EGL is not initialized for dpy.
  4983. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4984. if (EGL.stringCache[name]) return EGL.stringCache[name];
  4985. var ret;
  4986. switch (name) {
  4987. case 0x3053 /* EGL_VENDOR */: ret = stringToNewUTF8("Emscripten"); break;
  4988. case 0x3054 /* EGL_VERSION */: ret = stringToNewUTF8("1.4 Emscripten EGL"); break;
  4989. case 0x3055 /* EGL_EXTENSIONS */: ret = stringToNewUTF8(""); break; // Currently not supporting any EGL extensions.
  4990. case 0x308D /* EGL_CLIENT_APIS */: ret = stringToNewUTF8("OpenGL_ES"); break;
  4991. default:
  4992. EGL.setErrorCode(0x300C /* EGL_BAD_PARAMETER */);
  4993. return 0;
  4994. }
  4995. EGL.stringCache[name] = ret;
  4996. return ret;
  4997. };
  4998. var _eglSwapBuffers = (dpy, surface) => {
  4999. if (!EGL.defaultDisplayInitialized) {
  5000. EGL.setErrorCode(0x3001 /* EGL_NOT_INITIALIZED */);
  5001. } else if (!GLctx) {
  5002. EGL.setErrorCode(0x3002 /* EGL_BAD_ACCESS */);
  5003. } else if (GLctx.isContextLost()) {
  5004. EGL.setErrorCode(0x300E /* EGL_CONTEXT_LOST */);
  5005. } else {
  5006. // According to documentation this does an implicit flush.
  5007. // Due to discussion at https://github.com/emscripten-core/emscripten/pull/1871
  5008. // the flush was removed since this _may_ result in slowing code down.
  5009. //_glFlush();
  5010. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  5011. return 1 /* EGL_TRUE */;
  5012. }
  5013. return 0 /* EGL_FALSE */;
  5014. };
  5015. var _emscripten_get_now = () => performance.now();
  5016. /**
  5017. * @param {number=} arg
  5018. * @param {boolean=} noSetTiming
  5019. */
  5020. var setMainLoop = (iterFunc, fps, simulateInfiniteLoop, arg, noSetTiming) => {
  5021. assert(!MainLoop.func, 'emscripten_set_main_loop: there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one before setting a new one with different parameters.');
  5022. MainLoop.func = iterFunc;
  5023. MainLoop.arg = arg;
  5024. var thisMainLoopId = MainLoop.currentlyRunningMainloop;
  5025. function checkIsRunning() {
  5026. if (thisMainLoopId < MainLoop.currentlyRunningMainloop) {
  5027. runtimeKeepalivePop();
  5028. maybeExit();
  5029. return false;
  5030. }
  5031. return true;
  5032. }
  5033. // We create the loop runner here but it is not actually running until
  5034. // _emscripten_set_main_loop_timing is called (which might happen a
  5035. // later time). This member signifies that the current runner has not
  5036. // yet been started so that we can call runtimeKeepalivePush when it
  5037. // gets it timing set for the first time.
  5038. MainLoop.running = false;
  5039. MainLoop.runner = function MainLoop_runner() {
  5040. if (ABORT) return;
  5041. if (MainLoop.queue.length > 0) {
  5042. var start = Date.now();
  5043. var blocker = MainLoop.queue.shift();
  5044. blocker.func(blocker.arg);
  5045. if (MainLoop.remainingBlockers) {
  5046. var remaining = MainLoop.remainingBlockers;
  5047. var next = remaining%1 == 0 ? remaining-1 : Math.floor(remaining);
  5048. if (blocker.counted) {
  5049. MainLoop.remainingBlockers = next;
  5050. } else {
  5051. // not counted, but move the progress along a tiny bit
  5052. next = next + 0.5; // do not steal all the next one's progress
  5053. MainLoop.remainingBlockers = (8*remaining + next)/9;
  5054. }
  5055. }
  5056. MainLoop.updateStatus();
  5057. // catches pause/resume main loop from blocker execution
  5058. if (!checkIsRunning()) return;
  5059. setTimeout(MainLoop.runner, 0);
  5060. return;
  5061. }
  5062. // catch pauses from non-main loop sources
  5063. if (!checkIsRunning()) return;
  5064. // Implement very basic swap interval control
  5065. MainLoop.currentFrameNumber = MainLoop.currentFrameNumber + 1 | 0;
  5066. if (MainLoop.timingMode == 1 && MainLoop.timingValue > 1 && MainLoop.currentFrameNumber % MainLoop.timingValue != 0) {
  5067. // Not the scheduled time to render this frame - skip.
  5068. MainLoop.scheduler();
  5069. return;
  5070. } else if (MainLoop.timingMode == 0) {
  5071. MainLoop.tickStartTime = _emscripten_get_now();
  5072. }
  5073. if (MainLoop.method === 'timeout' && Module.ctx) {
  5074. warnOnce('Looks like you are rendering without using requestAnimationFrame for the main loop. You should use 0 for the frame rate in emscripten_set_main_loop in order to use requestAnimationFrame, as that can greatly improve your frame rates!');
  5075. MainLoop.method = ''; // just warn once per call to set main loop
  5076. }
  5077. MainLoop.runIter(iterFunc);
  5078. // catch pauses from the main loop itself
  5079. if (!checkIsRunning()) return;
  5080. MainLoop.scheduler();
  5081. }
  5082. if (!noSetTiming) {
  5083. if (fps && fps > 0) {
  5084. _emscripten_set_main_loop_timing(0, 1000.0 / fps);
  5085. } else {
  5086. // Do rAF by rendering each frame (no decimating)
  5087. _emscripten_set_main_loop_timing(1, 1);
  5088. }
  5089. MainLoop.scheduler();
  5090. }
  5091. if (simulateInfiniteLoop) {
  5092. throw 'unwind';
  5093. }
  5094. };
  5095. var MainLoop = {
  5096. running:false,
  5097. scheduler:null,
  5098. method:"",
  5099. currentlyRunningMainloop:0,
  5100. func:null,
  5101. arg:0,
  5102. timingMode:0,
  5103. timingValue:0,
  5104. currentFrameNumber:0,
  5105. queue:[],
  5106. preMainLoop:[],
  5107. postMainLoop:[],
  5108. pause() {
  5109. MainLoop.scheduler = null;
  5110. // Incrementing this signals the previous main loop that it's now become old, and it must return.
  5111. MainLoop.currentlyRunningMainloop++;
  5112. },
  5113. resume() {
  5114. MainLoop.currentlyRunningMainloop++;
  5115. var timingMode = MainLoop.timingMode;
  5116. var timingValue = MainLoop.timingValue;
  5117. var func = MainLoop.func;
  5118. MainLoop.func = null;
  5119. // do not set timing and call scheduler, we will do it on the next lines
  5120. setMainLoop(func, 0, false, MainLoop.arg, true);
  5121. _emscripten_set_main_loop_timing(timingMode, timingValue);
  5122. MainLoop.scheduler();
  5123. },
  5124. updateStatus() {
  5125. if (Module['setStatus']) {
  5126. var message = Module['statusMessage'] || 'Please wait...';
  5127. var remaining = MainLoop.remainingBlockers ?? 0;
  5128. var expected = MainLoop.expectedBlockers ?? 0;
  5129. if (remaining) {
  5130. if (remaining < expected) {
  5131. Module['setStatus'](`{message} ({expected - remaining}/{expected})`);
  5132. } else {
  5133. Module['setStatus'](message);
  5134. }
  5135. } else {
  5136. Module['setStatus']('');
  5137. }
  5138. }
  5139. },
  5140. init() {
  5141. Module['preMainLoop'] && MainLoop.preMainLoop.push(Module['preMainLoop']);
  5142. Module['postMainLoop'] && MainLoop.postMainLoop.push(Module['postMainLoop']);
  5143. },
  5144. runIter(func) {
  5145. if (ABORT) return;
  5146. for (var pre of MainLoop.preMainLoop) {
  5147. if (pre() === false) {
  5148. return; // |return false| skips a frame
  5149. }
  5150. }
  5151. callUserCallback(func);
  5152. for (var post of MainLoop.postMainLoop) {
  5153. post();
  5154. }
  5155. checkStackCookie();
  5156. },
  5157. nextRAF:0,
  5158. fakeRequestAnimationFrame(func) {
  5159. // try to keep 60fps between calls to here
  5160. var now = Date.now();
  5161. if (MainLoop.nextRAF === 0) {
  5162. MainLoop.nextRAF = now + 1000/60;
  5163. } else {
  5164. while (now + 2 >= MainLoop.nextRAF) { // fudge a little, to avoid timer jitter causing us to do lots of delay:0
  5165. MainLoop.nextRAF += 1000/60;
  5166. }
  5167. }
  5168. var delay = Math.max(MainLoop.nextRAF - now, 0);
  5169. setTimeout(func, delay);
  5170. },
  5171. requestAnimationFrame(func) {
  5172. if (typeof requestAnimationFrame == 'function') {
  5173. requestAnimationFrame(func);
  5174. return;
  5175. }
  5176. var RAF = MainLoop.fakeRequestAnimationFrame;
  5177. RAF(func);
  5178. },
  5179. };
  5180. var _emscripten_set_main_loop_timing = (mode, value) => {
  5181. MainLoop.timingMode = mode;
  5182. MainLoop.timingValue = value;
  5183. if (!MainLoop.func) {
  5184. err('emscripten_set_main_loop_timing: Cannot set timing mode for main loop since a main loop does not exist! Call emscripten_set_main_loop first to set one up.');
  5185. return 1; // Return non-zero on failure, can't set timing mode when there is no main loop.
  5186. }
  5187. if (!MainLoop.running) {
  5188. runtimeKeepalivePush();
  5189. MainLoop.running = true;
  5190. }
  5191. if (mode == 0) {
  5192. MainLoop.scheduler = function MainLoop_scheduler_setTimeout() {
  5193. var timeUntilNextTick = Math.max(0, MainLoop.tickStartTime + value - _emscripten_get_now())|0;
  5194. setTimeout(MainLoop.runner, timeUntilNextTick); // doing this each time means that on exception, we stop
  5195. };
  5196. MainLoop.method = 'timeout';
  5197. } else if (mode == 1) {
  5198. MainLoop.scheduler = function MainLoop_scheduler_rAF() {
  5199. MainLoop.requestAnimationFrame(MainLoop.runner);
  5200. };
  5201. MainLoop.method = 'rAF';
  5202. } else if (mode == 2) {
  5203. if (typeof MainLoop.setImmediate == 'undefined') {
  5204. if (typeof setImmediate == 'undefined') {
  5205. // Emulate setImmediate. (note: not a complete polyfill, we don't emulate clearImmediate() to keep code size to minimum, since not needed)
  5206. var setImmediates = [];
  5207. var emscriptenMainLoopMessageId = 'setimmediate';
  5208. /** @param {Event} event */
  5209. var MainLoop_setImmediate_messageHandler = (event) => {
  5210. // When called in current thread or Worker, the main loop ID is structured slightly different to accommodate for --proxy-to-worker runtime listening to Worker events,
  5211. // so check for both cases.
  5212. if (event.data === emscriptenMainLoopMessageId || event.data.target === emscriptenMainLoopMessageId) {
  5213. event.stopPropagation();
  5214. setImmediates.shift()();
  5215. }
  5216. };
  5217. addEventListener("message", MainLoop_setImmediate_messageHandler, true);
  5218. MainLoop.setImmediate = /** @type{function(function(): ?, ...?): number} */((func) => {
  5219. setImmediates.push(func);
  5220. if (ENVIRONMENT_IS_WORKER) {
  5221. Module['setImmediates'] ??= [];
  5222. Module['setImmediates'].push(func);
  5223. postMessage({target: emscriptenMainLoopMessageId}); // In --proxy-to-worker, route the message via proxyClient.js
  5224. } else postMessage(emscriptenMainLoopMessageId, "*"); // On the main thread, can just send the message to itself.
  5225. });
  5226. } else {
  5227. MainLoop.setImmediate = setImmediate;
  5228. }
  5229. }
  5230. MainLoop.scheduler = function MainLoop_scheduler_setImmediate() {
  5231. MainLoop.setImmediate(MainLoop.runner);
  5232. };
  5233. MainLoop.method = 'immediate';
  5234. }
  5235. return 0;
  5236. };
  5237. var _eglSwapInterval = (display, interval) => {
  5238. if (display != 62000) {
  5239. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  5240. return 0;
  5241. }
  5242. if (interval == 0) _emscripten_set_main_loop_timing(0, 0);
  5243. else _emscripten_set_main_loop_timing(1, interval);
  5244. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  5245. return 1;
  5246. };
  5247. var _eglTerminate = (display) => {
  5248. if (display != 62000) {
  5249. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  5250. return 0;
  5251. }
  5252. EGL.currentContext = 0;
  5253. EGL.currentReadSurface = 0;
  5254. EGL.currentDrawSurface = 0;
  5255. EGL.defaultDisplayInitialized = false;
  5256. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  5257. return 1;
  5258. };
  5259. /** @suppress {duplicate } */
  5260. var _eglWaitClient = () => {
  5261. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  5262. return 1;
  5263. };
  5264. var _eglWaitGL = _eglWaitClient;
  5265. var _eglWaitNative = (nativeEngineId) => {
  5266. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  5267. return 1;
  5268. };
  5269. var readEmAsmArgsArray = [];
  5270. var readEmAsmArgs = (sigPtr, buf) => {
  5271. // Nobody should have mutated _readEmAsmArgsArray underneath us to be something else than an array.
  5272. assert(Array.isArray(readEmAsmArgsArray));
  5273. // The input buffer is allocated on the stack, so it must be stack-aligned.
  5274. assert(buf % 16 == 0);
  5275. readEmAsmArgsArray.length = 0;
  5276. var ch;
  5277. // Most arguments are i32s, so shift the buffer pointer so it is a plain
  5278. // index into HEAP32.
  5279. while (ch = HEAPU8[sigPtr++]) {
  5280. var chr = String.fromCharCode(ch);
  5281. var validChars = ['d', 'f', 'i', 'p'];
  5282. // In WASM_BIGINT mode we support passing i64 values as bigint.
  5283. validChars.push('j');
  5284. assert(validChars.includes(chr), `Invalid character ${ch}("${chr}") in readEmAsmArgs! Use only [${validChars}], and do not specify "v" for void return argument.`);
  5285. // Floats are always passed as doubles, so all types except for 'i'
  5286. // are 8 bytes and require alignment.
  5287. var wide = (ch != 105);
  5288. wide &= (ch != 112);
  5289. buf += wide && (buf % 8) ? 4 : 0;
  5290. readEmAsmArgsArray.push(
  5291. // Special case for pointers under wasm64 or CAN_ADDRESS_2GB mode.
  5292. ch == 112 ? HEAPU32[((buf)>>2)] :
  5293. ch == 106 ? HEAP64[((buf)>>3)] :
  5294. ch == 105 ?
  5295. HEAP32[((buf)>>2)] :
  5296. HEAPF64[((buf)>>3)]
  5297. );
  5298. buf += wide ? 8 : 4;
  5299. }
  5300. return readEmAsmArgsArray;
  5301. };
  5302. var runEmAsmFunction = (code, sigPtr, argbuf) => {
  5303. var args = readEmAsmArgs(sigPtr, argbuf);
  5304. assert(ASM_CONSTS.hasOwnProperty(code), `No EM_ASM constant found at address ${code}. The loaded WebAssembly file is likely out of sync with the generated JavaScript.`);
  5305. return ASM_CONSTS[code](...args);
  5306. };
  5307. var _emscripten_asm_const_int = (code, sigPtr, argbuf) => {
  5308. return runEmAsmFunction(code, sigPtr, argbuf);
  5309. };
  5310. var runMainThreadEmAsm = (emAsmAddr, sigPtr, argbuf, sync) => {
  5311. var args = readEmAsmArgs(sigPtr, argbuf);
  5312. assert(ASM_CONSTS.hasOwnProperty(emAsmAddr), `No EM_ASM constant found at address ${emAsmAddr}. The loaded WebAssembly file is likely out of sync with the generated JavaScript.`);
  5313. return ASM_CONSTS[emAsmAddr](...args);
  5314. };
  5315. var _emscripten_asm_const_int_sync_on_main_thread = (emAsmAddr, sigPtr, argbuf) => runMainThreadEmAsm(emAsmAddr, sigPtr, argbuf, 1);
  5316. var _emscripten_asm_const_ptr = (code, sigPtr, argbuf) => {
  5317. return runEmAsmFunction(code, sigPtr, argbuf);
  5318. };
  5319. var _emscripten_asm_const_ptr_sync_on_main_thread = (emAsmAddr, sigPtr, argbuf) => runMainThreadEmAsm(emAsmAddr, sigPtr, argbuf, 1);
  5320. var _emscripten_cancel_main_loop = () => {
  5321. MainLoop.pause();
  5322. MainLoop.func = null;
  5323. };
  5324. var _emscripten_date_now = () => Date.now();
  5325. var JSEvents = {
  5326. memcpy(target, src, size) {
  5327. HEAP8.set(HEAP8.subarray(src, src + size), target);
  5328. },
  5329. removeAllEventListeners() {
  5330. while (JSEvents.eventHandlers.length) {
  5331. JSEvents._removeHandler(JSEvents.eventHandlers.length - 1);
  5332. }
  5333. JSEvents.deferredCalls = [];
  5334. },
  5335. registerRemoveEventListeners() {
  5336. if (!JSEvents.removeEventListenersRegistered) {
  5337. __ATEXIT__.push(JSEvents.removeAllEventListeners);
  5338. JSEvents.removeEventListenersRegistered = true;
  5339. }
  5340. },
  5341. inEventHandler:0,
  5342. deferredCalls:[],
  5343. deferCall(targetFunction, precedence, argsList) {
  5344. function arraysHaveEqualContent(arrA, arrB) {
  5345. if (arrA.length != arrB.length) return false;
  5346. for (var i in arrA) {
  5347. if (arrA[i] != arrB[i]) return false;
  5348. }
  5349. return true;
  5350. }
  5351. // Test if the given call was already queued, and if so, don't add it again.
  5352. for (var call of JSEvents.deferredCalls) {
  5353. if (call.targetFunction == targetFunction && arraysHaveEqualContent(call.argsList, argsList)) {
  5354. return;
  5355. }
  5356. }
  5357. JSEvents.deferredCalls.push({
  5358. targetFunction,
  5359. precedence,
  5360. argsList
  5361. });
  5362. JSEvents.deferredCalls.sort((x,y) => x.precedence < y.precedence);
  5363. },
  5364. removeDeferredCalls(targetFunction) {
  5365. JSEvents.deferredCalls = JSEvents.deferredCalls.filter((call) => call.targetFunction != targetFunction);
  5366. },
  5367. canPerformEventHandlerRequests() {
  5368. if (navigator.userActivation) {
  5369. // Verify against transient activation status from UserActivation API
  5370. // whether it is possible to perform a request here without needing to defer. See
  5371. // https://developer.mozilla.org/en-US/docs/Web/Security/User_activation#transient_activation
  5372. // and https://caniuse.com/mdn-api_useractivation
  5373. // At the time of writing, Firefox does not support this API: https://bugzilla.mozilla.org/show_bug.cgi?id=1791079
  5374. return navigator.userActivation.isActive;
  5375. }
  5376. return JSEvents.inEventHandler && JSEvents.currentEventHandler.allowsDeferredCalls;
  5377. },
  5378. runDeferredCalls() {
  5379. if (!JSEvents.canPerformEventHandlerRequests()) {
  5380. return;
  5381. }
  5382. var deferredCalls = JSEvents.deferredCalls;
  5383. JSEvents.deferredCalls = [];
  5384. for (var call of deferredCalls) {
  5385. call.targetFunction(...call.argsList);
  5386. }
  5387. },
  5388. eventHandlers:[],
  5389. removeAllHandlersOnTarget:(target, eventTypeString) => {
  5390. for (var i = 0; i < JSEvents.eventHandlers.length; ++i) {
  5391. if (JSEvents.eventHandlers[i].target == target &&
  5392. (!eventTypeString || eventTypeString == JSEvents.eventHandlers[i].eventTypeString)) {
  5393. JSEvents._removeHandler(i--);
  5394. }
  5395. }
  5396. },
  5397. _removeHandler(i) {
  5398. var h = JSEvents.eventHandlers[i];
  5399. h.target.removeEventListener(h.eventTypeString, h.eventListenerFunc, h.useCapture);
  5400. JSEvents.eventHandlers.splice(i, 1);
  5401. },
  5402. registerOrRemoveHandler(eventHandler) {
  5403. if (!eventHandler.target) {
  5404. err('registerOrRemoveHandler: the target element for event handler registration does not exist, when processing the following event handler registration:');
  5405. console.dir(eventHandler);
  5406. return -4;
  5407. }
  5408. if (eventHandler.callbackfunc) {
  5409. eventHandler.eventListenerFunc = function(event) {
  5410. // Increment nesting count for the event handler.
  5411. ++JSEvents.inEventHandler;
  5412. JSEvents.currentEventHandler = eventHandler;
  5413. // Process any old deferred calls the user has placed.
  5414. JSEvents.runDeferredCalls();
  5415. // Process the actual event, calls back to user C code handler.
  5416. eventHandler.handlerFunc(event);
  5417. // Process any new deferred calls that were placed right now from this event handler.
  5418. JSEvents.runDeferredCalls();
  5419. // Out of event handler - restore nesting count.
  5420. --JSEvents.inEventHandler;
  5421. };
  5422. eventHandler.target.addEventListener(eventHandler.eventTypeString,
  5423. eventHandler.eventListenerFunc,
  5424. eventHandler.useCapture);
  5425. JSEvents.eventHandlers.push(eventHandler);
  5426. JSEvents.registerRemoveEventListeners();
  5427. } else {
  5428. for (var i = 0; i < JSEvents.eventHandlers.length; ++i) {
  5429. if (JSEvents.eventHandlers[i].target == eventHandler.target
  5430. && JSEvents.eventHandlers[i].eventTypeString == eventHandler.eventTypeString) {
  5431. JSEvents._removeHandler(i--);
  5432. }
  5433. }
  5434. }
  5435. return 0;
  5436. },
  5437. getNodeNameForTarget(target) {
  5438. if (!target) return '';
  5439. if (target == window) return '#window';
  5440. if (target == screen) return '#screen';
  5441. return target?.nodeName || '';
  5442. },
  5443. fullscreenEnabled() {
  5444. return document.fullscreenEnabled
  5445. // Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitFullscreenEnabled.
  5446. // TODO: If Safari at some point ships with unprefixed version, update the version check above.
  5447. || document.webkitFullscreenEnabled
  5448. ;
  5449. },
  5450. };
  5451. var currentFullscreenStrategy = {
  5452. };
  5453. var maybeCStringToJsString = (cString) => {
  5454. // "cString > 2" checks if the input is a number, and isn't of the special
  5455. // values we accept here, EMSCRIPTEN_EVENT_TARGET_* (which map to 0, 1, 2).
  5456. // In other words, if cString > 2 then it's a pointer to a valid place in
  5457. // memory, and points to a C string.
  5458. return cString > 2 ? UTF8ToString(cString) : cString;
  5459. };
  5460. /** @type {Object} */
  5461. var specialHTMLTargets = [0, typeof document != 'undefined' ? document : 0, typeof window != 'undefined' ? window : 0];
  5462. /** @suppress {duplicate } */
  5463. var findEventTarget = (target) => {
  5464. target = maybeCStringToJsString(target);
  5465. var domElement = specialHTMLTargets[target] || (typeof document != 'undefined' ? document.querySelector(target) : undefined);
  5466. return domElement;
  5467. };
  5468. var findCanvasEventTarget = findEventTarget;
  5469. var _emscripten_get_canvas_element_size = (target, width, height) => {
  5470. var canvas = findCanvasEventTarget(target);
  5471. if (!canvas) return -4;
  5472. HEAP32[((width)>>2)] = canvas.width;
  5473. HEAP32[((height)>>2)] = canvas.height;
  5474. };
  5475. var stackAlloc = (sz) => __emscripten_stack_alloc(sz);
  5476. var stringToUTF8OnStack = (str) => {
  5477. var size = lengthBytesUTF8(str) + 1;
  5478. var ret = stackAlloc(size);
  5479. stringToUTF8(str, ret, size);
  5480. return ret;
  5481. };
  5482. var getCanvasElementSize = (target) => {
  5483. var sp = stackSave();
  5484. var w = stackAlloc(8);
  5485. var h = w + 4;
  5486. var targetInt = stringToUTF8OnStack(target.id);
  5487. var ret = _emscripten_get_canvas_element_size(targetInt, w, h);
  5488. var size = [HEAP32[((w)>>2)], HEAP32[((h)>>2)]];
  5489. stackRestore(sp);
  5490. return size;
  5491. };
  5492. var _emscripten_set_canvas_element_size = (target, width, height) => {
  5493. var canvas = findCanvasEventTarget(target);
  5494. if (!canvas) return -4;
  5495. canvas.width = width;
  5496. canvas.height = height;
  5497. return 0;
  5498. };
  5499. var setCanvasElementSize = (target, width, height) => {
  5500. if (!target.controlTransferredOffscreen) {
  5501. target.width = width;
  5502. target.height = height;
  5503. } else {
  5504. // This function is being called from high-level JavaScript code instead of asm.js/Wasm,
  5505. // and it needs to synchronously proxy over to another thread, so marshal the string onto the heap to do the call.
  5506. var sp = stackSave();
  5507. var targetInt = stringToUTF8OnStack(target.id);
  5508. _emscripten_set_canvas_element_size(targetInt, width, height);
  5509. stackRestore(sp);
  5510. }
  5511. };
  5512. var wasmTableMirror = [];
  5513. /** @type {WebAssembly.Table} */
  5514. var wasmTable;
  5515. var getWasmTableEntry = (funcPtr) => {
  5516. var func = wasmTableMirror[funcPtr];
  5517. if (!func) {
  5518. if (funcPtr >= wasmTableMirror.length) wasmTableMirror.length = funcPtr + 1;
  5519. /** @suppress {checkTypes} */
  5520. wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr);
  5521. }
  5522. /** @suppress {checkTypes} */
  5523. assert(wasmTable.get(funcPtr) == func, 'JavaScript-side Wasm function table mirror is out of date!');
  5524. return func;
  5525. };
  5526. var registerRestoreOldStyle = (canvas) => {
  5527. var canvasSize = getCanvasElementSize(canvas);
  5528. var oldWidth = canvasSize[0];
  5529. var oldHeight = canvasSize[1];
  5530. var oldCssWidth = canvas.style.width;
  5531. var oldCssHeight = canvas.style.height;
  5532. var oldBackgroundColor = canvas.style.backgroundColor; // Chrome reads color from here.
  5533. var oldDocumentBackgroundColor = document.body.style.backgroundColor; // IE11 reads color from here.
  5534. // Firefox always has black background color.
  5535. var oldPaddingLeft = canvas.style.paddingLeft; // Chrome, FF, Safari
  5536. var oldPaddingRight = canvas.style.paddingRight;
  5537. var oldPaddingTop = canvas.style.paddingTop;
  5538. var oldPaddingBottom = canvas.style.paddingBottom;
  5539. var oldMarginLeft = canvas.style.marginLeft; // IE11
  5540. var oldMarginRight = canvas.style.marginRight;
  5541. var oldMarginTop = canvas.style.marginTop;
  5542. var oldMarginBottom = canvas.style.marginBottom;
  5543. var oldDocumentBodyMargin = document.body.style.margin;
  5544. var oldDocumentOverflow = document.documentElement.style.overflow; // Chrome, Firefox
  5545. var oldDocumentScroll = document.body.scroll; // IE
  5546. var oldImageRendering = canvas.style.imageRendering;
  5547. function restoreOldStyle() {
  5548. var fullscreenElement = document.fullscreenElement
  5549. || document.webkitFullscreenElement
  5550. ;
  5551. if (!fullscreenElement) {
  5552. document.removeEventListener('fullscreenchange', restoreOldStyle);
  5553. // Unprefixed Fullscreen API shipped in Chromium 71 (https://bugs.chromium.org/p/chromium/issues/detail?id=383813)
  5554. // As of Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitfullscreenchange. TODO: revisit this check once Safari ships unprefixed version.
  5555. document.removeEventListener('webkitfullscreenchange', restoreOldStyle);
  5556. setCanvasElementSize(canvas, oldWidth, oldHeight);
  5557. canvas.style.width = oldCssWidth;
  5558. canvas.style.height = oldCssHeight;
  5559. canvas.style.backgroundColor = oldBackgroundColor; // Chrome
  5560. // IE11 hack: assigning 'undefined' or an empty string to document.body.style.backgroundColor has no effect, so first assign back the default color
  5561. // before setting the undefined value. Setting undefined value is also important, or otherwise we would later treat that as something that the user
  5562. // had explicitly set so subsequent fullscreen transitions would not set background color properly.
  5563. if (!oldDocumentBackgroundColor) document.body.style.backgroundColor = 'white';
  5564. document.body.style.backgroundColor = oldDocumentBackgroundColor; // IE11
  5565. canvas.style.paddingLeft = oldPaddingLeft; // Chrome, FF, Safari
  5566. canvas.style.paddingRight = oldPaddingRight;
  5567. canvas.style.paddingTop = oldPaddingTop;
  5568. canvas.style.paddingBottom = oldPaddingBottom;
  5569. canvas.style.marginLeft = oldMarginLeft; // IE11
  5570. canvas.style.marginRight = oldMarginRight;
  5571. canvas.style.marginTop = oldMarginTop;
  5572. canvas.style.marginBottom = oldMarginBottom;
  5573. document.body.style.margin = oldDocumentBodyMargin;
  5574. document.documentElement.style.overflow = oldDocumentOverflow; // Chrome, Firefox
  5575. document.body.scroll = oldDocumentScroll; // IE
  5576. canvas.style.imageRendering = oldImageRendering;
  5577. if (canvas.GLctxObject) canvas.GLctxObject.GLctx.viewport(0, 0, oldWidth, oldHeight);
  5578. if (currentFullscreenStrategy.canvasResizedCallback) {
  5579. getWasmTableEntry(currentFullscreenStrategy.canvasResizedCallback)(37, 0, currentFullscreenStrategy.canvasResizedCallbackUserData);
  5580. }
  5581. }
  5582. }
  5583. document.addEventListener('fullscreenchange', restoreOldStyle);
  5584. // Unprefixed Fullscreen API shipped in Chromium 71 (https://bugs.chromium.org/p/chromium/issues/detail?id=383813)
  5585. // As of Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitfullscreenchange. TODO: revisit this check once Safari ships unprefixed version.
  5586. document.addEventListener('webkitfullscreenchange', restoreOldStyle);
  5587. return restoreOldStyle;
  5588. };
  5589. var setLetterbox = (element, topBottom, leftRight) => {
  5590. // Cannot use margin to specify letterboxes in FF or Chrome, since those ignore margins in fullscreen mode.
  5591. element.style.paddingLeft = element.style.paddingRight = leftRight + 'px';
  5592. element.style.paddingTop = element.style.paddingBottom = topBottom + 'px';
  5593. };
  5594. var getBoundingClientRect = (e) => specialHTMLTargets.indexOf(e) < 0 ? e.getBoundingClientRect() : {'left':0,'top':0};
  5595. var JSEvents_resizeCanvasForFullscreen = (target, strategy) => {
  5596. var restoreOldStyle = registerRestoreOldStyle(target);
  5597. var cssWidth = strategy.softFullscreen ? innerWidth : screen.width;
  5598. var cssHeight = strategy.softFullscreen ? innerHeight : screen.height;
  5599. var rect = getBoundingClientRect(target);
  5600. var windowedCssWidth = rect.width;
  5601. var windowedCssHeight = rect.height;
  5602. var canvasSize = getCanvasElementSize(target);
  5603. var windowedRttWidth = canvasSize[0];
  5604. var windowedRttHeight = canvasSize[1];
  5605. if (strategy.scaleMode == 3) {
  5606. setLetterbox(target, (cssHeight - windowedCssHeight) / 2, (cssWidth - windowedCssWidth) / 2);
  5607. cssWidth = windowedCssWidth;
  5608. cssHeight = windowedCssHeight;
  5609. } else if (strategy.scaleMode == 2) {
  5610. if (cssWidth*windowedRttHeight < windowedRttWidth*cssHeight) {
  5611. var desiredCssHeight = windowedRttHeight * cssWidth / windowedRttWidth;
  5612. setLetterbox(target, (cssHeight - desiredCssHeight) / 2, 0);
  5613. cssHeight = desiredCssHeight;
  5614. } else {
  5615. var desiredCssWidth = windowedRttWidth * cssHeight / windowedRttHeight;
  5616. setLetterbox(target, 0, (cssWidth - desiredCssWidth) / 2);
  5617. cssWidth = desiredCssWidth;
  5618. }
  5619. }
  5620. // If we are adding padding, must choose a background color or otherwise Chrome will give the
  5621. // padding a default white color. Do it only if user has not customized their own background color.
  5622. target.style.backgroundColor ||= 'black';
  5623. // IE11 does the same, but requires the color to be set in the document body.
  5624. document.body.style.backgroundColor ||= 'black'; // IE11
  5625. // Firefox always shows black letterboxes independent of style color.
  5626. target.style.width = cssWidth + 'px';
  5627. target.style.height = cssHeight + 'px';
  5628. if (strategy.filteringMode == 1) {
  5629. target.style.imageRendering = 'optimizeSpeed';
  5630. target.style.imageRendering = '-moz-crisp-edges';
  5631. target.style.imageRendering = '-o-crisp-edges';
  5632. target.style.imageRendering = '-webkit-optimize-contrast';
  5633. target.style.imageRendering = 'optimize-contrast';
  5634. target.style.imageRendering = 'crisp-edges';
  5635. target.style.imageRendering = 'pixelated';
  5636. }
  5637. var dpiScale = (strategy.canvasResolutionScaleMode == 2) ? devicePixelRatio : 1;
  5638. if (strategy.canvasResolutionScaleMode != 0) {
  5639. var newWidth = (cssWidth * dpiScale)|0;
  5640. var newHeight = (cssHeight * dpiScale)|0;
  5641. setCanvasElementSize(target, newWidth, newHeight);
  5642. if (target.GLctxObject) target.GLctxObject.GLctx.viewport(0, 0, newWidth, newHeight);
  5643. }
  5644. return restoreOldStyle;
  5645. };
  5646. var JSEvents_requestFullscreen = (target, strategy) => {
  5647. // EMSCRIPTEN_FULLSCREEN_SCALE_DEFAULT + EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE is a mode where no extra logic is performed to the DOM elements.
  5648. if (strategy.scaleMode != 0 || strategy.canvasResolutionScaleMode != 0) {
  5649. JSEvents_resizeCanvasForFullscreen(target, strategy);
  5650. }
  5651. if (target.requestFullscreen) {
  5652. target.requestFullscreen();
  5653. } else if (target.webkitRequestFullscreen) {
  5654. target.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
  5655. } else {
  5656. return JSEvents.fullscreenEnabled() ? -3 : -1;
  5657. }
  5658. currentFullscreenStrategy = strategy;
  5659. if (strategy.canvasResizedCallback) {
  5660. getWasmTableEntry(strategy.canvasResizedCallback)(37, 0, strategy.canvasResizedCallbackUserData);
  5661. }
  5662. return 0;
  5663. };
  5664. var _emscripten_exit_fullscreen = () => {
  5665. if (!JSEvents.fullscreenEnabled()) return -1;
  5666. // Make sure no queued up calls will fire after this.
  5667. JSEvents.removeDeferredCalls(JSEvents_requestFullscreen);
  5668. var d = specialHTMLTargets[1];
  5669. if (d.exitFullscreen) {
  5670. d.fullscreenElement && d.exitFullscreen();
  5671. } else if (d.webkitExitFullscreen) {
  5672. d.webkitFullscreenElement && d.webkitExitFullscreen();
  5673. } else {
  5674. return -1;
  5675. }
  5676. return 0;
  5677. };
  5678. var requestPointerLock = (target) => {
  5679. if (target.requestPointerLock) {
  5680. target.requestPointerLock();
  5681. } else {
  5682. // document.body is known to accept pointer lock, so use that to differentiate if the user passed a bad element,
  5683. // or if the whole browser just doesn't support the feature.
  5684. if (document.body.requestPointerLock
  5685. ) {
  5686. return -3;
  5687. }
  5688. return -1;
  5689. }
  5690. return 0;
  5691. };
  5692. var _emscripten_exit_pointerlock = () => {
  5693. // Make sure no queued up calls will fire after this.
  5694. JSEvents.removeDeferredCalls(requestPointerLock);
  5695. if (document.exitPointerLock) {
  5696. document.exitPointerLock();
  5697. } else {
  5698. return -1;
  5699. }
  5700. return 0;
  5701. };
  5702. var __emscripten_runtime_keepalive_clear = () => {
  5703. noExitRuntime = false;
  5704. runtimeKeepaliveCounter = 0;
  5705. };
  5706. var _emscripten_force_exit = (status) => {
  5707. __emscripten_runtime_keepalive_clear();
  5708. _exit(status);
  5709. };
  5710. var _emscripten_get_device_pixel_ratio = () => {
  5711. return (typeof devicePixelRatio == 'number' && devicePixelRatio) || 1.0;
  5712. };
  5713. var _emscripten_get_element_css_size = (target, width, height) => {
  5714. target = findEventTarget(target);
  5715. if (!target) return -4;
  5716. var rect = getBoundingClientRect(target);
  5717. HEAPF64[((width)>>3)] = rect.width;
  5718. HEAPF64[((height)>>3)] = rect.height;
  5719. return 0;
  5720. };
  5721. var fillGamepadEventData = (eventStruct, e) => {
  5722. HEAPF64[((eventStruct)>>3)] = e.timestamp;
  5723. for (var i = 0; i < e.axes.length; ++i) {
  5724. HEAPF64[(((eventStruct+i*8)+(16))>>3)] = e.axes[i];
  5725. }
  5726. for (var i = 0; i < e.buttons.length; ++i) {
  5727. if (typeof e.buttons[i] == 'object') {
  5728. HEAPF64[(((eventStruct+i*8)+(528))>>3)] = e.buttons[i].value;
  5729. } else {
  5730. HEAPF64[(((eventStruct+i*8)+(528))>>3)] = e.buttons[i];
  5731. }
  5732. }
  5733. for (var i = 0; i < e.buttons.length; ++i) {
  5734. if (typeof e.buttons[i] == 'object') {
  5735. HEAP8[(eventStruct+i)+(1040)] = e.buttons[i].pressed;
  5736. } else {
  5737. // Assigning a boolean to HEAP32, that's ok, but Closure would like to warn about it:
  5738. /** @suppress {checkTypes} */
  5739. HEAP8[(eventStruct+i)+(1040)] = e.buttons[i] == 1;
  5740. }
  5741. }
  5742. HEAP8[(eventStruct)+(1104)] = e.connected;
  5743. HEAP32[(((eventStruct)+(1108))>>2)] = e.index;
  5744. HEAP32[(((eventStruct)+(8))>>2)] = e.axes.length;
  5745. HEAP32[(((eventStruct)+(12))>>2)] = e.buttons.length;
  5746. stringToUTF8(e.id, eventStruct + 1112, 64);
  5747. stringToUTF8(e.mapping, eventStruct + 1176, 64);
  5748. };
  5749. var _emscripten_get_gamepad_status = (index, gamepadState) => {
  5750. if (!JSEvents.lastGamepadState) throw 'emscripten_get_gamepad_status() can only be called after having first called emscripten_sample_gamepad_data() and that function has returned EMSCRIPTEN_RESULT_SUCCESS!';
  5751. // INVALID_PARAM is returned on a Gamepad index that never was there.
  5752. if (index < 0 || index >= JSEvents.lastGamepadState.length) return -5;
  5753. // NO_DATA is returned on a Gamepad index that was removed.
  5754. // For previously disconnected gamepads there should be an empty slot (null/undefined/false) at the index.
  5755. // This is because gamepads must keep their original position in the array.
  5756. // For example, removing the first of two gamepads produces [null/undefined/false, gamepad].
  5757. if (!JSEvents.lastGamepadState[index]) return -7;
  5758. fillGamepadEventData(gamepadState, JSEvents.lastGamepadState[index]);
  5759. return 0;
  5760. };
  5761. var _emscripten_get_num_gamepads = () => {
  5762. if (!JSEvents.lastGamepadState) throw 'emscripten_get_num_gamepads() can only be called after having first called emscripten_sample_gamepad_data() and that function has returned EMSCRIPTEN_RESULT_SUCCESS!';
  5763. // N.B. Do not call emscripten_get_num_gamepads() unless having first called emscripten_sample_gamepad_data(), and that has returned EMSCRIPTEN_RESULT_SUCCESS.
  5764. // Otherwise the following line will throw an exception.
  5765. return JSEvents.lastGamepadState.length;
  5766. };
  5767. var _emscripten_get_screen_size = (width, height) => {
  5768. HEAP32[((width)>>2)] = screen.width;
  5769. HEAP32[((height)>>2)] = screen.height;
  5770. };
  5771. /** @suppress {duplicate } */
  5772. var _glActiveTexture = (x0) => GLctx.activeTexture(x0);
  5773. var _emscripten_glActiveTexture = _glActiveTexture;
  5774. /** @suppress {duplicate } */
  5775. var _glAttachShader = (program, shader) => {
  5776. GLctx.attachShader(GL.programs[program], GL.shaders[shader]);
  5777. };
  5778. var _emscripten_glAttachShader = _glAttachShader;
  5779. /** @suppress {duplicate } */
  5780. var _glBeginQueryEXT = (target, id) => {
  5781. GLctx.disjointTimerQueryExt['beginQueryEXT'](target, GL.queries[id]);
  5782. };
  5783. var _emscripten_glBeginQueryEXT = _glBeginQueryEXT;
  5784. /** @suppress {duplicate } */
  5785. var _glBindAttribLocation = (program, index, name) => {
  5786. GLctx.bindAttribLocation(GL.programs[program], index, UTF8ToString(name));
  5787. };
  5788. var _emscripten_glBindAttribLocation = _glBindAttribLocation;
  5789. /** @suppress {duplicate } */
  5790. var _glBindBuffer = (target, buffer) => {
  5791. GLctx.bindBuffer(target, GL.buffers[buffer]);
  5792. };
  5793. var _emscripten_glBindBuffer = _glBindBuffer;
  5794. /** @suppress {duplicate } */
  5795. var _glBindFramebuffer = (target, framebuffer) => {
  5796. GLctx.bindFramebuffer(target, GL.framebuffers[framebuffer]);
  5797. };
  5798. var _emscripten_glBindFramebuffer = _glBindFramebuffer;
  5799. /** @suppress {duplicate } */
  5800. var _glBindRenderbuffer = (target, renderbuffer) => {
  5801. GLctx.bindRenderbuffer(target, GL.renderbuffers[renderbuffer]);
  5802. };
  5803. var _emscripten_glBindRenderbuffer = _glBindRenderbuffer;
  5804. /** @suppress {duplicate } */
  5805. var _glBindTexture = (target, texture) => {
  5806. GLctx.bindTexture(target, GL.textures[texture]);
  5807. };
  5808. var _emscripten_glBindTexture = _glBindTexture;
  5809. /** @suppress {duplicate } */
  5810. var _glBindVertexArray = (vao) => {
  5811. GLctx.bindVertexArray(GL.vaos[vao]);
  5812. };
  5813. /** @suppress {duplicate } */
  5814. var _glBindVertexArrayOES = _glBindVertexArray;
  5815. var _emscripten_glBindVertexArrayOES = _glBindVertexArrayOES;
  5816. /** @suppress {duplicate } */
  5817. var _glBlendColor = (x0, x1, x2, x3) => GLctx.blendColor(x0, x1, x2, x3);
  5818. var _emscripten_glBlendColor = _glBlendColor;
  5819. /** @suppress {duplicate } */
  5820. var _glBlendEquation = (x0) => GLctx.blendEquation(x0);
  5821. var _emscripten_glBlendEquation = _glBlendEquation;
  5822. /** @suppress {duplicate } */
  5823. var _glBlendEquationSeparate = (x0, x1) => GLctx.blendEquationSeparate(x0, x1);
  5824. var _emscripten_glBlendEquationSeparate = _glBlendEquationSeparate;
  5825. /** @suppress {duplicate } */
  5826. var _glBlendFunc = (x0, x1) => GLctx.blendFunc(x0, x1);
  5827. var _emscripten_glBlendFunc = _glBlendFunc;
  5828. /** @suppress {duplicate } */
  5829. var _glBlendFuncSeparate = (x0, x1, x2, x3) => GLctx.blendFuncSeparate(x0, x1, x2, x3);
  5830. var _emscripten_glBlendFuncSeparate = _glBlendFuncSeparate;
  5831. /** @suppress {duplicate } */
  5832. var _glBufferData = (target, size, data, usage) => {
  5833. // N.b. here first form specifies a heap subarray, second form an integer
  5834. // size, so the ?: code here is polymorphic. It is advised to avoid
  5835. // randomly mixing both uses in calling code, to avoid any potential JS
  5836. // engine JIT issues.
  5837. GLctx.bufferData(target, data ? HEAPU8.subarray(data, data+size) : size, usage);
  5838. };
  5839. var _emscripten_glBufferData = _glBufferData;
  5840. /** @suppress {duplicate } */
  5841. var _glBufferSubData = (target, offset, size, data) => {
  5842. GLctx.bufferSubData(target, offset, HEAPU8.subarray(data, data+size));
  5843. };
  5844. var _emscripten_glBufferSubData = _glBufferSubData;
  5845. /** @suppress {duplicate } */
  5846. var _glCheckFramebufferStatus = (x0) => GLctx.checkFramebufferStatus(x0);
  5847. var _emscripten_glCheckFramebufferStatus = _glCheckFramebufferStatus;
  5848. /** @suppress {duplicate } */
  5849. var _glClear = (x0) => GLctx.clear(x0);
  5850. var _emscripten_glClear = _glClear;
  5851. /** @suppress {duplicate } */
  5852. var _glClearColor = (x0, x1, x2, x3) => GLctx.clearColor(x0, x1, x2, x3);
  5853. var _emscripten_glClearColor = _glClearColor;
  5854. /** @suppress {duplicate } */
  5855. var _glClearDepthf = (x0) => GLctx.clearDepth(x0);
  5856. var _emscripten_glClearDepthf = _glClearDepthf;
  5857. /** @suppress {duplicate } */
  5858. var _glClearStencil = (x0) => GLctx.clearStencil(x0);
  5859. var _emscripten_glClearStencil = _glClearStencil;
  5860. /** @suppress {duplicate } */
  5861. var _glClipControlEXT = (origin, depth) => {
  5862. GLctx.extClipControl['clipControlEXT'](origin, depth);
  5863. };
  5864. var _emscripten_glClipControlEXT = _glClipControlEXT;
  5865. /** @suppress {duplicate } */
  5866. var _glColorMask = (red, green, blue, alpha) => {
  5867. GLctx.colorMask(!!red, !!green, !!blue, !!alpha);
  5868. };
  5869. var _emscripten_glColorMask = _glColorMask;
  5870. /** @suppress {duplicate } */
  5871. var _glCompileShader = (shader) => {
  5872. GLctx.compileShader(GL.shaders[shader]);
  5873. };
  5874. var _emscripten_glCompileShader = _glCompileShader;
  5875. /** @suppress {duplicate } */
  5876. var _glCompressedTexImage2D = (target, level, internalFormat, width, height, border, imageSize, data) => {
  5877. // `data` may be null here, which means "allocate uniniitalized space but
  5878. // don't upload" in GLES parlance, but `compressedTexImage2D` requires the
  5879. // final data parameter, so we simply pass a heap view starting at zero
  5880. // effectively uploading whatever happens to be near address zero. See
  5881. // https://github.com/emscripten-core/emscripten/issues/19300.
  5882. GLctx.compressedTexImage2D(target, level, internalFormat, width, height, border, HEAPU8.subarray((data), data+imageSize));
  5883. };
  5884. var _emscripten_glCompressedTexImage2D = _glCompressedTexImage2D;
  5885. /** @suppress {duplicate } */
  5886. var _glCompressedTexSubImage2D = (target, level, xoffset, yoffset, width, height, format, imageSize, data) => {
  5887. GLctx.compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, HEAPU8.subarray((data), data+imageSize));
  5888. };
  5889. var _emscripten_glCompressedTexSubImage2D = _glCompressedTexSubImage2D;
  5890. /** @suppress {duplicate } */
  5891. var _glCopyTexImage2D = (x0, x1, x2, x3, x4, x5, x6, x7) => GLctx.copyTexImage2D(x0, x1, x2, x3, x4, x5, x6, x7);
  5892. var _emscripten_glCopyTexImage2D = _glCopyTexImage2D;
  5893. /** @suppress {duplicate } */
  5894. var _glCopyTexSubImage2D = (x0, x1, x2, x3, x4, x5, x6, x7) => GLctx.copyTexSubImage2D(x0, x1, x2, x3, x4, x5, x6, x7);
  5895. var _emscripten_glCopyTexSubImage2D = _glCopyTexSubImage2D;
  5896. /** @suppress {duplicate } */
  5897. var _glCreateProgram = () => {
  5898. var id = GL.getNewId(GL.programs);
  5899. var program = GLctx.createProgram();
  5900. // Store additional information needed for each shader program:
  5901. program.name = id;
  5902. // Lazy cache results of
  5903. // glGetProgramiv(GL_ACTIVE_UNIFORM_MAX_LENGTH/GL_ACTIVE_ATTRIBUTE_MAX_LENGTH/GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH)
  5904. program.maxUniformLength = program.maxAttributeLength = program.maxUniformBlockNameLength = 0;
  5905. program.uniformIdCounter = 1;
  5906. GL.programs[id] = program;
  5907. return id;
  5908. };
  5909. var _emscripten_glCreateProgram = _glCreateProgram;
  5910. /** @suppress {duplicate } */
  5911. var _glCreateShader = (shaderType) => {
  5912. var id = GL.getNewId(GL.shaders);
  5913. GL.shaders[id] = GLctx.createShader(shaderType);
  5914. return id;
  5915. };
  5916. var _emscripten_glCreateShader = _glCreateShader;
  5917. /** @suppress {duplicate } */
  5918. var _glCullFace = (x0) => GLctx.cullFace(x0);
  5919. var _emscripten_glCullFace = _glCullFace;
  5920. /** @suppress {duplicate } */
  5921. var _glDeleteBuffers = (n, buffers) => {
  5922. for (var i = 0; i < n; i++) {
  5923. var id = HEAP32[(((buffers)+(i*4))>>2)];
  5924. var buffer = GL.buffers[id];
  5925. // From spec: "glDeleteBuffers silently ignores 0's and names that do not
  5926. // correspond to existing buffer objects."
  5927. if (!buffer) continue;
  5928. GLctx.deleteBuffer(buffer);
  5929. buffer.name = 0;
  5930. GL.buffers[id] = null;
  5931. }
  5932. };
  5933. var _emscripten_glDeleteBuffers = _glDeleteBuffers;
  5934. /** @suppress {duplicate } */
  5935. var _glDeleteFramebuffers = (n, framebuffers) => {
  5936. for (var i = 0; i < n; ++i) {
  5937. var id = HEAP32[(((framebuffers)+(i*4))>>2)];
  5938. var framebuffer = GL.framebuffers[id];
  5939. if (!framebuffer) continue; // GL spec: "glDeleteFramebuffers silently ignores 0s and names that do not correspond to existing framebuffer objects".
  5940. GLctx.deleteFramebuffer(framebuffer);
  5941. framebuffer.name = 0;
  5942. GL.framebuffers[id] = null;
  5943. }
  5944. };
  5945. var _emscripten_glDeleteFramebuffers = _glDeleteFramebuffers;
  5946. /** @suppress {duplicate } */
  5947. var _glDeleteProgram = (id) => {
  5948. if (!id) return;
  5949. var program = GL.programs[id];
  5950. if (!program) {
  5951. // glDeleteProgram actually signals an error when deleting a nonexisting
  5952. // object, unlike some other GL delete functions.
  5953. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  5954. return;
  5955. }
  5956. GLctx.deleteProgram(program);
  5957. program.name = 0;
  5958. GL.programs[id] = null;
  5959. };
  5960. var _emscripten_glDeleteProgram = _glDeleteProgram;
  5961. /** @suppress {duplicate } */
  5962. var _glDeleteQueriesEXT = (n, ids) => {
  5963. for (var i = 0; i < n; i++) {
  5964. var id = HEAP32[(((ids)+(i*4))>>2)];
  5965. var query = GL.queries[id];
  5966. if (!query) continue; // GL spec: "unused names in ids are ignored, as is the name zero."
  5967. GLctx.disjointTimerQueryExt['deleteQueryEXT'](query);
  5968. GL.queries[id] = null;
  5969. }
  5970. };
  5971. var _emscripten_glDeleteQueriesEXT = _glDeleteQueriesEXT;
  5972. /** @suppress {duplicate } */
  5973. var _glDeleteRenderbuffers = (n, renderbuffers) => {
  5974. for (var i = 0; i < n; i++) {
  5975. var id = HEAP32[(((renderbuffers)+(i*4))>>2)];
  5976. var renderbuffer = GL.renderbuffers[id];
  5977. if (!renderbuffer) continue; // GL spec: "glDeleteRenderbuffers silently ignores 0s and names that do not correspond to existing renderbuffer objects".
  5978. GLctx.deleteRenderbuffer(renderbuffer);
  5979. renderbuffer.name = 0;
  5980. GL.renderbuffers[id] = null;
  5981. }
  5982. };
  5983. var _emscripten_glDeleteRenderbuffers = _glDeleteRenderbuffers;
  5984. /** @suppress {duplicate } */
  5985. var _glDeleteShader = (id) => {
  5986. if (!id) return;
  5987. var shader = GL.shaders[id];
  5988. if (!shader) {
  5989. // glDeleteShader actually signals an error when deleting a nonexisting
  5990. // object, unlike some other GL delete functions.
  5991. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  5992. return;
  5993. }
  5994. GLctx.deleteShader(shader);
  5995. GL.shaders[id] = null;
  5996. };
  5997. var _emscripten_glDeleteShader = _glDeleteShader;
  5998. /** @suppress {duplicate } */
  5999. var _glDeleteTextures = (n, textures) => {
  6000. for (var i = 0; i < n; i++) {
  6001. var id = HEAP32[(((textures)+(i*4))>>2)];
  6002. var texture = GL.textures[id];
  6003. // GL spec: "glDeleteTextures silently ignores 0s and names that do not
  6004. // correspond to existing textures".
  6005. if (!texture) continue;
  6006. GLctx.deleteTexture(texture);
  6007. texture.name = 0;
  6008. GL.textures[id] = null;
  6009. }
  6010. };
  6011. var _emscripten_glDeleteTextures = _glDeleteTextures;
  6012. /** @suppress {duplicate } */
  6013. var _glDeleteVertexArrays = (n, vaos) => {
  6014. for (var i = 0; i < n; i++) {
  6015. var id = HEAP32[(((vaos)+(i*4))>>2)];
  6016. GLctx.deleteVertexArray(GL.vaos[id]);
  6017. GL.vaos[id] = null;
  6018. }
  6019. };
  6020. /** @suppress {duplicate } */
  6021. var _glDeleteVertexArraysOES = _glDeleteVertexArrays;
  6022. var _emscripten_glDeleteVertexArraysOES = _glDeleteVertexArraysOES;
  6023. /** @suppress {duplicate } */
  6024. var _glDepthFunc = (x0) => GLctx.depthFunc(x0);
  6025. var _emscripten_glDepthFunc = _glDepthFunc;
  6026. /** @suppress {duplicate } */
  6027. var _glDepthMask = (flag) => {
  6028. GLctx.depthMask(!!flag);
  6029. };
  6030. var _emscripten_glDepthMask = _glDepthMask;
  6031. /** @suppress {duplicate } */
  6032. var _glDepthRangef = (x0, x1) => GLctx.depthRange(x0, x1);
  6033. var _emscripten_glDepthRangef = _glDepthRangef;
  6034. /** @suppress {duplicate } */
  6035. var _glDetachShader = (program, shader) => {
  6036. GLctx.detachShader(GL.programs[program], GL.shaders[shader]);
  6037. };
  6038. var _emscripten_glDetachShader = _glDetachShader;
  6039. /** @suppress {duplicate } */
  6040. var _glDisable = (x0) => GLctx.disable(x0);
  6041. var _emscripten_glDisable = _glDisable;
  6042. /** @suppress {duplicate } */
  6043. var _glDisableVertexAttribArray = (index) => {
  6044. GLctx.disableVertexAttribArray(index);
  6045. };
  6046. var _emscripten_glDisableVertexAttribArray = _glDisableVertexAttribArray;
  6047. /** @suppress {duplicate } */
  6048. var _glDrawArrays = (mode, first, count) => {
  6049. GLctx.drawArrays(mode, first, count);
  6050. };
  6051. var _emscripten_glDrawArrays = _glDrawArrays;
  6052. /** @suppress {duplicate } */
  6053. var _glDrawArraysInstanced = (mode, first, count, primcount) => {
  6054. GLctx.drawArraysInstanced(mode, first, count, primcount);
  6055. };
  6056. /** @suppress {duplicate } */
  6057. var _glDrawArraysInstancedANGLE = _glDrawArraysInstanced;
  6058. var _emscripten_glDrawArraysInstancedANGLE = _glDrawArraysInstancedANGLE;
  6059. var tempFixedLengthArray = [];
  6060. /** @suppress {duplicate } */
  6061. var _glDrawBuffers = (n, bufs) => {
  6062. var bufArray = tempFixedLengthArray[n];
  6063. for (var i = 0; i < n; i++) {
  6064. bufArray[i] = HEAP32[(((bufs)+(i*4))>>2)];
  6065. }
  6066. GLctx.drawBuffers(bufArray);
  6067. };
  6068. /** @suppress {duplicate } */
  6069. var _glDrawBuffersWEBGL = _glDrawBuffers;
  6070. var _emscripten_glDrawBuffersWEBGL = _glDrawBuffersWEBGL;
  6071. /** @suppress {duplicate } */
  6072. var _glDrawElements = (mode, count, type, indices) => {
  6073. GLctx.drawElements(mode, count, type, indices);
  6074. };
  6075. var _emscripten_glDrawElements = _glDrawElements;
  6076. /** @suppress {duplicate } */
  6077. var _glDrawElementsInstanced = (mode, count, type, indices, primcount) => {
  6078. GLctx.drawElementsInstanced(mode, count, type, indices, primcount);
  6079. };
  6080. /** @suppress {duplicate } */
  6081. var _glDrawElementsInstancedANGLE = _glDrawElementsInstanced;
  6082. var _emscripten_glDrawElementsInstancedANGLE = _glDrawElementsInstancedANGLE;
  6083. /** @suppress {duplicate } */
  6084. var _glEnable = (x0) => GLctx.enable(x0);
  6085. var _emscripten_glEnable = _glEnable;
  6086. /** @suppress {duplicate } */
  6087. var _glEnableVertexAttribArray = (index) => {
  6088. GLctx.enableVertexAttribArray(index);
  6089. };
  6090. var _emscripten_glEnableVertexAttribArray = _glEnableVertexAttribArray;
  6091. /** @suppress {duplicate } */
  6092. var _glEndQueryEXT = (target) => {
  6093. GLctx.disjointTimerQueryExt['endQueryEXT'](target);
  6094. };
  6095. var _emscripten_glEndQueryEXT = _glEndQueryEXT;
  6096. /** @suppress {duplicate } */
  6097. var _glFinish = () => GLctx.finish();
  6098. var _emscripten_glFinish = _glFinish;
  6099. /** @suppress {duplicate } */
  6100. var _glFlush = () => GLctx.flush();
  6101. var _emscripten_glFlush = _glFlush;
  6102. /** @suppress {duplicate } */
  6103. var _glFramebufferRenderbuffer = (target, attachment, renderbuffertarget, renderbuffer) => {
  6104. GLctx.framebufferRenderbuffer(target, attachment, renderbuffertarget,
  6105. GL.renderbuffers[renderbuffer]);
  6106. };
  6107. var _emscripten_glFramebufferRenderbuffer = _glFramebufferRenderbuffer;
  6108. /** @suppress {duplicate } */
  6109. var _glFramebufferTexture2D = (target, attachment, textarget, texture, level) => {
  6110. GLctx.framebufferTexture2D(target, attachment, textarget,
  6111. GL.textures[texture], level);
  6112. };
  6113. var _emscripten_glFramebufferTexture2D = _glFramebufferTexture2D;
  6114. /** @suppress {duplicate } */
  6115. var _glFrontFace = (x0) => GLctx.frontFace(x0);
  6116. var _emscripten_glFrontFace = _glFrontFace;
  6117. /** @suppress {duplicate } */
  6118. var _glGenBuffers = (n, buffers) => {
  6119. GL.genObject(n, buffers, 'createBuffer', GL.buffers
  6120. );
  6121. };
  6122. var _emscripten_glGenBuffers = _glGenBuffers;
  6123. /** @suppress {duplicate } */
  6124. var _glGenFramebuffers = (n, ids) => {
  6125. GL.genObject(n, ids, 'createFramebuffer', GL.framebuffers
  6126. );
  6127. };
  6128. var _emscripten_glGenFramebuffers = _glGenFramebuffers;
  6129. /** @suppress {duplicate } */
  6130. var _glGenQueriesEXT = (n, ids) => {
  6131. for (var i = 0; i < n; i++) {
  6132. var query = GLctx.disjointTimerQueryExt['createQueryEXT']();
  6133. if (!query) {
  6134. GL.recordError(0x502 /* GL_INVALID_OPERATION */);
  6135. while (i < n) HEAP32[(((ids)+(i++*4))>>2)] = 0;
  6136. return;
  6137. }
  6138. var id = GL.getNewId(GL.queries);
  6139. query.name = id;
  6140. GL.queries[id] = query;
  6141. HEAP32[(((ids)+(i*4))>>2)] = id;
  6142. }
  6143. };
  6144. var _emscripten_glGenQueriesEXT = _glGenQueriesEXT;
  6145. /** @suppress {duplicate } */
  6146. var _glGenRenderbuffers = (n, renderbuffers) => {
  6147. GL.genObject(n, renderbuffers, 'createRenderbuffer', GL.renderbuffers
  6148. );
  6149. };
  6150. var _emscripten_glGenRenderbuffers = _glGenRenderbuffers;
  6151. /** @suppress {duplicate } */
  6152. var _glGenTextures = (n, textures) => {
  6153. GL.genObject(n, textures, 'createTexture', GL.textures
  6154. );
  6155. };
  6156. var _emscripten_glGenTextures = _glGenTextures;
  6157. /** @suppress {duplicate } */
  6158. var _glGenVertexArrays = (n, arrays) => {
  6159. GL.genObject(n, arrays, 'createVertexArray', GL.vaos
  6160. );
  6161. };
  6162. /** @suppress {duplicate } */
  6163. var _glGenVertexArraysOES = _glGenVertexArrays;
  6164. var _emscripten_glGenVertexArraysOES = _glGenVertexArraysOES;
  6165. /** @suppress {duplicate } */
  6166. var _glGenerateMipmap = (x0) => GLctx.generateMipmap(x0);
  6167. var _emscripten_glGenerateMipmap = _glGenerateMipmap;
  6168. var __glGetActiveAttribOrUniform = (funcName, program, index, bufSize, length, size, type, name) => {
  6169. program = GL.programs[program];
  6170. var info = GLctx[funcName](program, index);
  6171. if (info) {
  6172. // If an error occurs, nothing will be written to length, size and type and name.
  6173. var numBytesWrittenExclNull = name && stringToUTF8(info.name, name, bufSize);
  6174. if (length) HEAP32[((length)>>2)] = numBytesWrittenExclNull;
  6175. if (size) HEAP32[((size)>>2)] = info.size;
  6176. if (type) HEAP32[((type)>>2)] = info.type;
  6177. }
  6178. };
  6179. /** @suppress {duplicate } */
  6180. var _glGetActiveAttrib = (program, index, bufSize, length, size, type, name) => {
  6181. __glGetActiveAttribOrUniform('getActiveAttrib', program, index, bufSize, length, size, type, name);
  6182. };
  6183. var _emscripten_glGetActiveAttrib = _glGetActiveAttrib;
  6184. /** @suppress {duplicate } */
  6185. var _glGetActiveUniform = (program, index, bufSize, length, size, type, name) => {
  6186. __glGetActiveAttribOrUniform('getActiveUniform', program, index, bufSize, length, size, type, name);
  6187. };
  6188. var _emscripten_glGetActiveUniform = _glGetActiveUniform;
  6189. /** @suppress {duplicate } */
  6190. var _glGetAttachedShaders = (program, maxCount, count, shaders) => {
  6191. var result = GLctx.getAttachedShaders(GL.programs[program]);
  6192. var len = result.length;
  6193. if (len > maxCount) {
  6194. len = maxCount;
  6195. }
  6196. HEAP32[((count)>>2)] = len;
  6197. for (var i = 0; i < len; ++i) {
  6198. var id = GL.shaders.indexOf(result[i]);
  6199. HEAP32[(((shaders)+(i*4))>>2)] = id;
  6200. }
  6201. };
  6202. var _emscripten_glGetAttachedShaders = _glGetAttachedShaders;
  6203. /** @suppress {duplicate } */
  6204. var _glGetAttribLocation = (program, name) => {
  6205. return GLctx.getAttribLocation(GL.programs[program], UTF8ToString(name));
  6206. };
  6207. var _emscripten_glGetAttribLocation = _glGetAttribLocation;
  6208. var readI53FromI64 = (ptr) => {
  6209. return HEAPU32[((ptr)>>2)] + HEAP32[(((ptr)+(4))>>2)] * 4294967296;
  6210. };
  6211. var readI53FromU64 = (ptr) => {
  6212. return HEAPU32[((ptr)>>2)] + HEAPU32[(((ptr)+(4))>>2)] * 4294967296;
  6213. };
  6214. var writeI53ToI64 = (ptr, num) => {
  6215. HEAPU32[((ptr)>>2)] = num;
  6216. var lower = HEAPU32[((ptr)>>2)];
  6217. HEAPU32[(((ptr)+(4))>>2)] = (num - lower)/4294967296;
  6218. var deserialized = (num >= 0) ? readI53FromU64(ptr) : readI53FromI64(ptr);
  6219. var offset = ((ptr)>>2);
  6220. if (deserialized != num) warnOnce(`writeI53ToI64() out of range: serialized JS Number ${num} to Wasm heap as bytes lo=${ptrToString(HEAPU32[offset])}, hi=${ptrToString(HEAPU32[offset+1])}, which deserializes back to ${deserialized} instead!`);
  6221. };
  6222. var emscriptenWebGLGet = (name_, p, type) => {
  6223. // Guard against user passing a null pointer.
  6224. // Note that GLES2 spec does not say anything about how passing a null
  6225. // pointer should be treated. Testing on desktop core GL 3, the application
  6226. // crashes on glGetIntegerv to a null pointer, but better to report an error
  6227. // instead of doing anything random.
  6228. if (!p) {
  6229. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6230. return;
  6231. }
  6232. var ret = undefined;
  6233. switch (name_) { // Handle a few trivial GLES values
  6234. case 0x8DFA: // GL_SHADER_COMPILER
  6235. ret = 1;
  6236. break;
  6237. case 0x8DF8: // GL_SHADER_BINARY_FORMATS
  6238. if (type != 0 && type != 1) {
  6239. GL.recordError(0x500); // GL_INVALID_ENUM
  6240. }
  6241. // Do not write anything to the out pointer, since no binary formats are
  6242. // supported.
  6243. return;
  6244. case 0x8DF9: // GL_NUM_SHADER_BINARY_FORMATS
  6245. ret = 0;
  6246. break;
  6247. case 0x86A2: // GL_NUM_COMPRESSED_TEXTURE_FORMATS
  6248. // WebGL doesn't have GL_NUM_COMPRESSED_TEXTURE_FORMATS (it's obsolete
  6249. // since GL_COMPRESSED_TEXTURE_FORMATS returns a JS array that can be
  6250. // queried for length), so implement it ourselves to allow C++ GLES2
  6251. // code get the length.
  6252. var formats = GLctx.getParameter(0x86A3 /*GL_COMPRESSED_TEXTURE_FORMATS*/);
  6253. ret = formats ? formats.length : 0;
  6254. break;
  6255. }
  6256. if (ret === undefined) {
  6257. var result = GLctx.getParameter(name_);
  6258. switch (typeof result) {
  6259. case "number":
  6260. ret = result;
  6261. break;
  6262. case "boolean":
  6263. ret = result ? 1 : 0;
  6264. break;
  6265. case "string":
  6266. GL.recordError(0x500); // GL_INVALID_ENUM
  6267. return;
  6268. case "object":
  6269. if (result === null) {
  6270. // null is a valid result for some (e.g., which buffer is bound -
  6271. // perhaps nothing is bound), but otherwise can mean an invalid
  6272. // name_, which we need to report as an error
  6273. switch (name_) {
  6274. case 0x8894: // ARRAY_BUFFER_BINDING
  6275. case 0x8B8D: // CURRENT_PROGRAM
  6276. case 0x8895: // ELEMENT_ARRAY_BUFFER_BINDING
  6277. case 0x8CA6: // FRAMEBUFFER_BINDING or DRAW_FRAMEBUFFER_BINDING
  6278. case 0x8CA7: // RENDERBUFFER_BINDING
  6279. case 0x8069: // TEXTURE_BINDING_2D
  6280. case 0x85B5: // WebGL 2 GL_VERTEX_ARRAY_BINDING, or WebGL 1 extension OES_vertex_array_object GL_VERTEX_ARRAY_BINDING_OES
  6281. case 0x8514: { // TEXTURE_BINDING_CUBE_MAP
  6282. ret = 0;
  6283. break;
  6284. }
  6285. default: {
  6286. GL.recordError(0x500); // GL_INVALID_ENUM
  6287. return;
  6288. }
  6289. }
  6290. } else if (result instanceof Float32Array ||
  6291. result instanceof Uint32Array ||
  6292. result instanceof Int32Array ||
  6293. result instanceof Array) {
  6294. for (var i = 0; i < result.length; ++i) {
  6295. switch (type) {
  6296. case 0: HEAP32[(((p)+(i*4))>>2)] = result[i]; break;
  6297. case 2: HEAPF32[(((p)+(i*4))>>2)] = result[i]; break;
  6298. case 4: HEAP8[(p)+(i)] = result[i] ? 1 : 0; break;
  6299. }
  6300. }
  6301. return;
  6302. } else {
  6303. try {
  6304. ret = result.name | 0;
  6305. } catch(e) {
  6306. GL.recordError(0x500); // GL_INVALID_ENUM
  6307. err(`GL_INVALID_ENUM in glGet${type}v: Unknown object returned from WebGL getParameter(${name_})! (error: ${e})`);
  6308. return;
  6309. }
  6310. }
  6311. break;
  6312. default:
  6313. GL.recordError(0x500); // GL_INVALID_ENUM
  6314. err(`GL_INVALID_ENUM in glGet${type}v: Native code calling glGet${type}v(${name_}) and it returns ${result} of type ${typeof(result)}!`);
  6315. return;
  6316. }
  6317. }
  6318. switch (type) {
  6319. case 1: writeI53ToI64(p, ret); break;
  6320. case 0: HEAP32[((p)>>2)] = ret; break;
  6321. case 2: HEAPF32[((p)>>2)] = ret; break;
  6322. case 4: HEAP8[p] = ret ? 1 : 0; break;
  6323. }
  6324. };
  6325. /** @suppress {duplicate } */
  6326. var _glGetBooleanv = (name_, p) => emscriptenWebGLGet(name_, p, 4);
  6327. var _emscripten_glGetBooleanv = _glGetBooleanv;
  6328. /** @suppress {duplicate } */
  6329. var _glGetBufferParameteriv = (target, value, data) => {
  6330. if (!data) {
  6331. // GLES2 specification does not specify how to behave if data is a null
  6332. // pointer. Since calling this function does not make sense if data ==
  6333. // null, issue a GL error to notify user about it.
  6334. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6335. return;
  6336. }
  6337. HEAP32[((data)>>2)] = GLctx.getBufferParameter(target, value);
  6338. };
  6339. var _emscripten_glGetBufferParameteriv = _glGetBufferParameteriv;
  6340. /** @suppress {duplicate } */
  6341. var _glGetError = () => {
  6342. var error = GLctx.getError() || GL.lastError;
  6343. GL.lastError = 0/*GL_NO_ERROR*/;
  6344. return error;
  6345. };
  6346. var _emscripten_glGetError = _glGetError;
  6347. /** @suppress {duplicate } */
  6348. var _glGetFloatv = (name_, p) => emscriptenWebGLGet(name_, p, 2);
  6349. var _emscripten_glGetFloatv = _glGetFloatv;
  6350. /** @suppress {duplicate } */
  6351. var _glGetFramebufferAttachmentParameteriv = (target, attachment, pname, params) => {
  6352. var result = GLctx.getFramebufferAttachmentParameter(target, attachment, pname);
  6353. if (result instanceof WebGLRenderbuffer ||
  6354. result instanceof WebGLTexture) {
  6355. result = result.name | 0;
  6356. }
  6357. HEAP32[((params)>>2)] = result;
  6358. };
  6359. var _emscripten_glGetFramebufferAttachmentParameteriv = _glGetFramebufferAttachmentParameteriv;
  6360. /** @suppress {duplicate } */
  6361. var _glGetIntegerv = (name_, p) => emscriptenWebGLGet(name_, p, 0);
  6362. var _emscripten_glGetIntegerv = _glGetIntegerv;
  6363. /** @suppress {duplicate } */
  6364. var _glGetProgramInfoLog = (program, maxLength, length, infoLog) => {
  6365. var log = GLctx.getProgramInfoLog(GL.programs[program]);
  6366. if (log === null) log = '(unknown error)';
  6367. var numBytesWrittenExclNull = (maxLength > 0 && infoLog) ? stringToUTF8(log, infoLog, maxLength) : 0;
  6368. if (length) HEAP32[((length)>>2)] = numBytesWrittenExclNull;
  6369. };
  6370. var _emscripten_glGetProgramInfoLog = _glGetProgramInfoLog;
  6371. /** @suppress {duplicate } */
  6372. var _glGetProgramiv = (program, pname, p) => {
  6373. if (!p) {
  6374. // GLES2 specification does not specify how to behave if p is a null
  6375. // pointer. Since calling this function does not make sense if p == null,
  6376. // issue a GL error to notify user about it.
  6377. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6378. return;
  6379. }
  6380. if (program >= GL.counter) {
  6381. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6382. return;
  6383. }
  6384. program = GL.programs[program];
  6385. if (pname == 0x8B84) { // GL_INFO_LOG_LENGTH
  6386. var log = GLctx.getProgramInfoLog(program);
  6387. if (log === null) log = '(unknown error)';
  6388. HEAP32[((p)>>2)] = log.length + 1;
  6389. } else if (pname == 0x8B87 /* GL_ACTIVE_UNIFORM_MAX_LENGTH */) {
  6390. if (!program.maxUniformLength) {
  6391. var numActiveUniforms = GLctx.getProgramParameter(program, 0x8B86/*GL_ACTIVE_UNIFORMS*/);
  6392. for (var i = 0; i < numActiveUniforms; ++i) {
  6393. program.maxUniformLength = Math.max(program.maxUniformLength, GLctx.getActiveUniform(program, i).name.length+1);
  6394. }
  6395. }
  6396. HEAP32[((p)>>2)] = program.maxUniformLength;
  6397. } else if (pname == 0x8B8A /* GL_ACTIVE_ATTRIBUTE_MAX_LENGTH */) {
  6398. if (!program.maxAttributeLength) {
  6399. var numActiveAttributes = GLctx.getProgramParameter(program, 0x8B89/*GL_ACTIVE_ATTRIBUTES*/);
  6400. for (var i = 0; i < numActiveAttributes; ++i) {
  6401. program.maxAttributeLength = Math.max(program.maxAttributeLength, GLctx.getActiveAttrib(program, i).name.length+1);
  6402. }
  6403. }
  6404. HEAP32[((p)>>2)] = program.maxAttributeLength;
  6405. } else if (pname == 0x8A35 /* GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH */) {
  6406. if (!program.maxUniformBlockNameLength) {
  6407. var numActiveUniformBlocks = GLctx.getProgramParameter(program, 0x8A36/*GL_ACTIVE_UNIFORM_BLOCKS*/);
  6408. for (var i = 0; i < numActiveUniformBlocks; ++i) {
  6409. program.maxUniformBlockNameLength = Math.max(program.maxUniformBlockNameLength, GLctx.getActiveUniformBlockName(program, i).length+1);
  6410. }
  6411. }
  6412. HEAP32[((p)>>2)] = program.maxUniformBlockNameLength;
  6413. } else {
  6414. HEAP32[((p)>>2)] = GLctx.getProgramParameter(program, pname);
  6415. }
  6416. };
  6417. var _emscripten_glGetProgramiv = _glGetProgramiv;
  6418. /** @suppress {duplicate } */
  6419. var _glGetQueryObjecti64vEXT = (id, pname, params) => {
  6420. if (!params) {
  6421. // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
  6422. // if p == null, issue a GL error to notify user about it.
  6423. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6424. return;
  6425. }
  6426. var query = GL.queries[id];
  6427. var param;
  6428. {
  6429. param = GLctx.disjointTimerQueryExt['getQueryObjectEXT'](query, pname);
  6430. }
  6431. var ret;
  6432. if (typeof param == 'boolean') {
  6433. ret = param ? 1 : 0;
  6434. } else {
  6435. ret = param;
  6436. }
  6437. writeI53ToI64(params, ret);
  6438. };
  6439. var _emscripten_glGetQueryObjecti64vEXT = _glGetQueryObjecti64vEXT;
  6440. /** @suppress {duplicate } */
  6441. var _glGetQueryObjectivEXT = (id, pname, params) => {
  6442. if (!params) {
  6443. // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
  6444. // if p == null, issue a GL error to notify user about it.
  6445. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6446. return;
  6447. }
  6448. var query = GL.queries[id];
  6449. var param = GLctx.disjointTimerQueryExt['getQueryObjectEXT'](query, pname);
  6450. var ret;
  6451. if (typeof param == 'boolean') {
  6452. ret = param ? 1 : 0;
  6453. } else {
  6454. ret = param;
  6455. }
  6456. HEAP32[((params)>>2)] = ret;
  6457. };
  6458. var _emscripten_glGetQueryObjectivEXT = _glGetQueryObjectivEXT;
  6459. /** @suppress {duplicate } */
  6460. var _glGetQueryObjectui64vEXT = _glGetQueryObjecti64vEXT;
  6461. var _emscripten_glGetQueryObjectui64vEXT = _glGetQueryObjectui64vEXT;
  6462. /** @suppress {duplicate } */
  6463. var _glGetQueryObjectuivEXT = _glGetQueryObjectivEXT;
  6464. var _emscripten_glGetQueryObjectuivEXT = _glGetQueryObjectuivEXT;
  6465. /** @suppress {duplicate } */
  6466. var _glGetQueryivEXT = (target, pname, params) => {
  6467. if (!params) {
  6468. // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
  6469. // if p == null, issue a GL error to notify user about it.
  6470. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6471. return;
  6472. }
  6473. HEAP32[((params)>>2)] = GLctx.disjointTimerQueryExt['getQueryEXT'](target, pname);
  6474. };
  6475. var _emscripten_glGetQueryivEXT = _glGetQueryivEXT;
  6476. /** @suppress {duplicate } */
  6477. var _glGetRenderbufferParameteriv = (target, pname, params) => {
  6478. if (!params) {
  6479. // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
  6480. // if params == null, issue a GL error to notify user about it.
  6481. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6482. return;
  6483. }
  6484. HEAP32[((params)>>2)] = GLctx.getRenderbufferParameter(target, pname);
  6485. };
  6486. var _emscripten_glGetRenderbufferParameteriv = _glGetRenderbufferParameteriv;
  6487. /** @suppress {duplicate } */
  6488. var _glGetShaderInfoLog = (shader, maxLength, length, infoLog) => {
  6489. var log = GLctx.getShaderInfoLog(GL.shaders[shader]);
  6490. if (log === null) log = '(unknown error)';
  6491. var numBytesWrittenExclNull = (maxLength > 0 && infoLog) ? stringToUTF8(log, infoLog, maxLength) : 0;
  6492. if (length) HEAP32[((length)>>2)] = numBytesWrittenExclNull;
  6493. };
  6494. var _emscripten_glGetShaderInfoLog = _glGetShaderInfoLog;
  6495. /** @suppress {duplicate } */
  6496. var _glGetShaderPrecisionFormat = (shaderType, precisionType, range, precision) => {
  6497. var result = GLctx.getShaderPrecisionFormat(shaderType, precisionType);
  6498. HEAP32[((range)>>2)] = result.rangeMin;
  6499. HEAP32[(((range)+(4))>>2)] = result.rangeMax;
  6500. HEAP32[((precision)>>2)] = result.precision;
  6501. };
  6502. var _emscripten_glGetShaderPrecisionFormat = _glGetShaderPrecisionFormat;
  6503. /** @suppress {duplicate } */
  6504. var _glGetShaderSource = (shader, bufSize, length, source) => {
  6505. var result = GLctx.getShaderSource(GL.shaders[shader]);
  6506. if (!result) return; // If an error occurs, nothing will be written to length or source.
  6507. var numBytesWrittenExclNull = (bufSize > 0 && source) ? stringToUTF8(result, source, bufSize) : 0;
  6508. if (length) HEAP32[((length)>>2)] = numBytesWrittenExclNull;
  6509. };
  6510. var _emscripten_glGetShaderSource = _glGetShaderSource;
  6511. /** @suppress {duplicate } */
  6512. var _glGetShaderiv = (shader, pname, p) => {
  6513. if (!p) {
  6514. // GLES2 specification does not specify how to behave if p is a null
  6515. // pointer. Since calling this function does not make sense if p == null,
  6516. // issue a GL error to notify user about it.
  6517. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6518. return;
  6519. }
  6520. if (pname == 0x8B84) { // GL_INFO_LOG_LENGTH
  6521. var log = GLctx.getShaderInfoLog(GL.shaders[shader]);
  6522. if (log === null) log = '(unknown error)';
  6523. // The GLES2 specification says that if the shader has an empty info log,
  6524. // a value of 0 is returned. Otherwise the log has a null char appended.
  6525. // (An empty string is falsey, so we can just check that instead of
  6526. // looking at log.length.)
  6527. var logLength = log ? log.length + 1 : 0;
  6528. HEAP32[((p)>>2)] = logLength;
  6529. } else if (pname == 0x8B88) { // GL_SHADER_SOURCE_LENGTH
  6530. var source = GLctx.getShaderSource(GL.shaders[shader]);
  6531. // source may be a null, or the empty string, both of which are falsey
  6532. // values that we report a 0 length for.
  6533. var sourceLength = source ? source.length + 1 : 0;
  6534. HEAP32[((p)>>2)] = sourceLength;
  6535. } else {
  6536. HEAP32[((p)>>2)] = GLctx.getShaderParameter(GL.shaders[shader], pname);
  6537. }
  6538. };
  6539. var _emscripten_glGetShaderiv = _glGetShaderiv;
  6540. var webglGetExtensions = function $webglGetExtensions() {
  6541. var exts = getEmscriptenSupportedExtensions(GLctx);
  6542. exts = exts.concat(exts.map((e) => "GL_" + e));
  6543. return exts;
  6544. };
  6545. /** @suppress {duplicate } */
  6546. var _glGetString = (name_) => {
  6547. var ret = GL.stringCache[name_];
  6548. if (!ret) {
  6549. switch (name_) {
  6550. case 0x1F03 /* GL_EXTENSIONS */:
  6551. ret = stringToNewUTF8(webglGetExtensions().join(' '));
  6552. break;
  6553. case 0x1F00 /* GL_VENDOR */:
  6554. case 0x1F01 /* GL_RENDERER */:
  6555. case 0x9245 /* UNMASKED_VENDOR_WEBGL */:
  6556. case 0x9246 /* UNMASKED_RENDERER_WEBGL */:
  6557. var s = GLctx.getParameter(name_);
  6558. if (!s) {
  6559. GL.recordError(0x500/*GL_INVALID_ENUM*/);
  6560. }
  6561. ret = s ? stringToNewUTF8(s) : 0;
  6562. break;
  6563. case 0x1F02 /* GL_VERSION */:
  6564. var webGLVersion = GLctx.getParameter(0x1F02 /*GL_VERSION*/);
  6565. // return GLES version string corresponding to the version of the WebGL context
  6566. var glVersion = `OpenGL ES 2.0 (${webGLVersion})`;
  6567. ret = stringToNewUTF8(glVersion);
  6568. break;
  6569. case 0x8B8C /* GL_SHADING_LANGUAGE_VERSION */:
  6570. var glslVersion = GLctx.getParameter(0x8B8C /*GL_SHADING_LANGUAGE_VERSION*/);
  6571. // extract the version number 'N.M' from the string 'WebGL GLSL ES N.M ...'
  6572. var ver_re = /^WebGL GLSL ES ([0-9]\.[0-9][0-9]?)(?:$| .*)/;
  6573. var ver_num = glslVersion.match(ver_re);
  6574. if (ver_num !== null) {
  6575. if (ver_num[1].length == 3) ver_num[1] = ver_num[1] + '0'; // ensure minor version has 2 digits
  6576. glslVersion = `OpenGL ES GLSL ES ${ver_num[1]} (${glslVersion})`;
  6577. }
  6578. ret = stringToNewUTF8(glslVersion);
  6579. break;
  6580. default:
  6581. GL.recordError(0x500/*GL_INVALID_ENUM*/);
  6582. // fall through
  6583. }
  6584. GL.stringCache[name_] = ret;
  6585. }
  6586. return ret;
  6587. };
  6588. var _emscripten_glGetString = _glGetString;
  6589. /** @suppress {duplicate } */
  6590. var _glGetTexParameterfv = (target, pname, params) => {
  6591. if (!params) {
  6592. // GLES2 specification does not specify how to behave if params is a null
  6593. // pointer. Since calling this function does not make sense if p == null,
  6594. // issue a GL error to notify user about it.
  6595. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6596. return;
  6597. }
  6598. HEAPF32[((params)>>2)] = GLctx.getTexParameter(target, pname);
  6599. };
  6600. var _emscripten_glGetTexParameterfv = _glGetTexParameterfv;
  6601. /** @suppress {duplicate } */
  6602. var _glGetTexParameteriv = (target, pname, params) => {
  6603. if (!params) {
  6604. // GLES2 specification does not specify how to behave if params is a null
  6605. // pointer. Since calling this function does not make sense if p == null,
  6606. // issue a GL error to notify user about it.
  6607. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6608. return;
  6609. }
  6610. HEAP32[((params)>>2)] = GLctx.getTexParameter(target, pname);
  6611. };
  6612. var _emscripten_glGetTexParameteriv = _glGetTexParameteriv;
  6613. /** @suppress {checkTypes} */
  6614. var jstoi_q = (str) => parseInt(str);
  6615. /** @noinline */
  6616. var webglGetLeftBracePos = (name) => name.slice(-1) == ']' && name.lastIndexOf('[');
  6617. var webglPrepareUniformLocationsBeforeFirstUse = (program) => {
  6618. var uniformLocsById = program.uniformLocsById, // Maps GLuint -> WebGLUniformLocation
  6619. uniformSizeAndIdsByName = program.uniformSizeAndIdsByName, // Maps name -> [uniform array length, GLuint]
  6620. i, j;
  6621. // On the first time invocation of glGetUniformLocation on this shader program:
  6622. // initialize cache data structures and discover which uniforms are arrays.
  6623. if (!uniformLocsById) {
  6624. // maps GLint integer locations to WebGLUniformLocations
  6625. program.uniformLocsById = uniformLocsById = {};
  6626. // maps integer locations back to uniform name strings, so that we can lazily fetch uniform array locations
  6627. program.uniformArrayNamesById = {};
  6628. var numActiveUniforms = GLctx.getProgramParameter(program, 0x8B86/*GL_ACTIVE_UNIFORMS*/);
  6629. for (i = 0; i < numActiveUniforms; ++i) {
  6630. var u = GLctx.getActiveUniform(program, i);
  6631. var nm = u.name;
  6632. var sz = u.size;
  6633. var lb = webglGetLeftBracePos(nm);
  6634. var arrayName = lb > 0 ? nm.slice(0, lb) : nm;
  6635. // Assign a new location.
  6636. var id = program.uniformIdCounter;
  6637. program.uniformIdCounter += sz;
  6638. // Eagerly get the location of the uniformArray[0] base element.
  6639. // The remaining indices >0 will be left for lazy evaluation to
  6640. // improve performance. Those may never be needed to fetch, if the
  6641. // application fills arrays always in full starting from the first
  6642. // element of the array.
  6643. uniformSizeAndIdsByName[arrayName] = [sz, id];
  6644. // Store placeholder integers in place that highlight that these
  6645. // >0 index locations are array indices pending population.
  6646. for (j = 0; j < sz; ++j) {
  6647. uniformLocsById[id] = j;
  6648. program.uniformArrayNamesById[id++] = arrayName;
  6649. }
  6650. }
  6651. }
  6652. };
  6653. /** @suppress {duplicate } */
  6654. var _glGetUniformLocation = (program, name) => {
  6655. name = UTF8ToString(name);
  6656. if (program = GL.programs[program]) {
  6657. webglPrepareUniformLocationsBeforeFirstUse(program);
  6658. var uniformLocsById = program.uniformLocsById; // Maps GLuint -> WebGLUniformLocation
  6659. var arrayIndex = 0;
  6660. var uniformBaseName = name;
  6661. // Invariant: when populating integer IDs for uniform locations, we must
  6662. // maintain the precondition that arrays reside in contiguous addresses,
  6663. // i.e. for a 'vec4 colors[10];', colors[4] must be at location
  6664. // colors[0]+4. However, user might call glGetUniformLocation(program,
  6665. // "colors") for an array, so we cannot discover based on the user input
  6666. // arguments whether the uniform we are dealing with is an array. The only
  6667. // way to discover which uniforms are arrays is to enumerate over all the
  6668. // active uniforms in the program.
  6669. var leftBrace = webglGetLeftBracePos(name);
  6670. // If user passed an array accessor "[index]", parse the array index off the accessor.
  6671. if (leftBrace > 0) {
  6672. arrayIndex = jstoi_q(name.slice(leftBrace + 1)) >>> 0; // "index]", coerce parseInt(']') with >>>0 to treat "foo[]" as "foo[0]" and foo[-1] as unsigned out-of-bounds.
  6673. uniformBaseName = name.slice(0, leftBrace);
  6674. }
  6675. // Have we cached the location of this uniform before?
  6676. // A pair [array length, GLint of the uniform location]
  6677. var sizeAndId = program.uniformSizeAndIdsByName[uniformBaseName];
  6678. // If an uniform with this name exists, and if its index is within the
  6679. // array limits (if it's even an array), query the WebGLlocation, or
  6680. // return an existing cached location.
  6681. if (sizeAndId && arrayIndex < sizeAndId[0]) {
  6682. arrayIndex += sizeAndId[1]; // Add the base location of the uniform to the array index offset.
  6683. if ((uniformLocsById[arrayIndex] = uniformLocsById[arrayIndex] || GLctx.getUniformLocation(program, name))) {
  6684. return arrayIndex;
  6685. }
  6686. }
  6687. }
  6688. else {
  6689. // N.b. we are currently unable to distinguish between GL program IDs that
  6690. // never existed vs GL program IDs that have been deleted, so report
  6691. // GL_INVALID_VALUE in both cases.
  6692. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6693. }
  6694. return -1;
  6695. };
  6696. var _emscripten_glGetUniformLocation = _glGetUniformLocation;
  6697. var webglGetUniformLocation = (location) => {
  6698. var p = GLctx.currentProgram;
  6699. if (p) {
  6700. var webglLoc = p.uniformLocsById[location];
  6701. // p.uniformLocsById[location] stores either an integer, or a
  6702. // WebGLUniformLocation.
  6703. // If an integer, we have not yet bound the location, so do it now. The
  6704. // integer value specifies the array index we should bind to.
  6705. if (typeof webglLoc == 'number') {
  6706. p.uniformLocsById[location] = webglLoc = GLctx.getUniformLocation(p, p.uniformArrayNamesById[location] + (webglLoc > 0 ? `[${webglLoc}]` : ''));
  6707. }
  6708. // Else an already cached WebGLUniformLocation, return it.
  6709. return webglLoc;
  6710. } else {
  6711. GL.recordError(0x502/*GL_INVALID_OPERATION*/);
  6712. }
  6713. };
  6714. /** @suppress{checkTypes} */
  6715. var emscriptenWebGLGetUniform = (program, location, params, type) => {
  6716. if (!params) {
  6717. // GLES2 specification does not specify how to behave if params is a null
  6718. // pointer. Since calling this function does not make sense if params ==
  6719. // null, issue a GL error to notify user about it.
  6720. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6721. return;
  6722. }
  6723. program = GL.programs[program];
  6724. webglPrepareUniformLocationsBeforeFirstUse(program);
  6725. var data = GLctx.getUniform(program, webglGetUniformLocation(location));
  6726. if (typeof data == 'number' || typeof data == 'boolean') {
  6727. switch (type) {
  6728. case 0: HEAP32[((params)>>2)] = data; break;
  6729. case 2: HEAPF32[((params)>>2)] = data; break;
  6730. }
  6731. } else {
  6732. for (var i = 0; i < data.length; i++) {
  6733. switch (type) {
  6734. case 0: HEAP32[(((params)+(i*4))>>2)] = data[i]; break;
  6735. case 2: HEAPF32[(((params)+(i*4))>>2)] = data[i]; break;
  6736. }
  6737. }
  6738. }
  6739. };
  6740. /** @suppress {duplicate } */
  6741. var _glGetUniformfv = (program, location, params) => {
  6742. emscriptenWebGLGetUniform(program, location, params, 2);
  6743. };
  6744. var _emscripten_glGetUniformfv = _glGetUniformfv;
  6745. /** @suppress {duplicate } */
  6746. var _glGetUniformiv = (program, location, params) => {
  6747. emscriptenWebGLGetUniform(program, location, params, 0);
  6748. };
  6749. var _emscripten_glGetUniformiv = _glGetUniformiv;
  6750. /** @suppress {duplicate } */
  6751. var _glGetVertexAttribPointerv = (index, pname, pointer) => {
  6752. if (!pointer) {
  6753. // GLES2 specification does not specify how to behave if pointer is a null
  6754. // pointer. Since calling this function does not make sense if pointer ==
  6755. // null, issue a GL error to notify user about it.
  6756. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6757. return;
  6758. }
  6759. HEAP32[((pointer)>>2)] = GLctx.getVertexAttribOffset(index, pname);
  6760. };
  6761. var _emscripten_glGetVertexAttribPointerv = _glGetVertexAttribPointerv;
  6762. /** @suppress{checkTypes} */
  6763. var emscriptenWebGLGetVertexAttrib = (index, pname, params, type) => {
  6764. if (!params) {
  6765. // GLES2 specification does not specify how to behave if params is a null
  6766. // pointer. Since calling this function does not make sense if params ==
  6767. // null, issue a GL error to notify user about it.
  6768. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6769. return;
  6770. }
  6771. var data = GLctx.getVertexAttrib(index, pname);
  6772. if (pname == 0x889F/*VERTEX_ATTRIB_ARRAY_BUFFER_BINDING*/) {
  6773. HEAP32[((params)>>2)] = data && data["name"];
  6774. } else if (typeof data == 'number' || typeof data == 'boolean') {
  6775. switch (type) {
  6776. case 0: HEAP32[((params)>>2)] = data; break;
  6777. case 2: HEAPF32[((params)>>2)] = data; break;
  6778. case 5: HEAP32[((params)>>2)] = Math.fround(data); break;
  6779. }
  6780. } else {
  6781. for (var i = 0; i < data.length; i++) {
  6782. switch (type) {
  6783. case 0: HEAP32[(((params)+(i*4))>>2)] = data[i]; break;
  6784. case 2: HEAPF32[(((params)+(i*4))>>2)] = data[i]; break;
  6785. case 5: HEAP32[(((params)+(i*4))>>2)] = Math.fround(data[i]); break;
  6786. }
  6787. }
  6788. }
  6789. };
  6790. /** @suppress {duplicate } */
  6791. var _glGetVertexAttribfv = (index, pname, params) => {
  6792. // N.B. This function may only be called if the vertex attribute was
  6793. // specified using the function glVertexAttrib*f(), otherwise the results
  6794. // are undefined. (GLES3 spec 6.1.12)
  6795. emscriptenWebGLGetVertexAttrib(index, pname, params, 2);
  6796. };
  6797. var _emscripten_glGetVertexAttribfv = _glGetVertexAttribfv;
  6798. /** @suppress {duplicate } */
  6799. var _glGetVertexAttribiv = (index, pname, params) => {
  6800. // N.B. This function may only be called if the vertex attribute was
  6801. // specified using the function glVertexAttrib*f(), otherwise the results
  6802. // are undefined. (GLES3 spec 6.1.12)
  6803. emscriptenWebGLGetVertexAttrib(index, pname, params, 5);
  6804. };
  6805. var _emscripten_glGetVertexAttribiv = _glGetVertexAttribiv;
  6806. /** @suppress {duplicate } */
  6807. var _glHint = (x0, x1) => GLctx.hint(x0, x1);
  6808. var _emscripten_glHint = _glHint;
  6809. /** @suppress {duplicate } */
  6810. var _glIsBuffer = (buffer) => {
  6811. var b = GL.buffers[buffer];
  6812. if (!b) return 0;
  6813. return GLctx.isBuffer(b);
  6814. };
  6815. var _emscripten_glIsBuffer = _glIsBuffer;
  6816. /** @suppress {duplicate } */
  6817. var _glIsEnabled = (x0) => GLctx.isEnabled(x0);
  6818. var _emscripten_glIsEnabled = _glIsEnabled;
  6819. /** @suppress {duplicate } */
  6820. var _glIsFramebuffer = (framebuffer) => {
  6821. var fb = GL.framebuffers[framebuffer];
  6822. if (!fb) return 0;
  6823. return GLctx.isFramebuffer(fb);
  6824. };
  6825. var _emscripten_glIsFramebuffer = _glIsFramebuffer;
  6826. /** @suppress {duplicate } */
  6827. var _glIsProgram = (program) => {
  6828. program = GL.programs[program];
  6829. if (!program) return 0;
  6830. return GLctx.isProgram(program);
  6831. };
  6832. var _emscripten_glIsProgram = _glIsProgram;
  6833. /** @suppress {duplicate } */
  6834. var _glIsQueryEXT = (id) => {
  6835. var query = GL.queries[id];
  6836. if (!query) return 0;
  6837. return GLctx.disjointTimerQueryExt['isQueryEXT'](query);
  6838. };
  6839. var _emscripten_glIsQueryEXT = _glIsQueryEXT;
  6840. /** @suppress {duplicate } */
  6841. var _glIsRenderbuffer = (renderbuffer) => {
  6842. var rb = GL.renderbuffers[renderbuffer];
  6843. if (!rb) return 0;
  6844. return GLctx.isRenderbuffer(rb);
  6845. };
  6846. var _emscripten_glIsRenderbuffer = _glIsRenderbuffer;
  6847. /** @suppress {duplicate } */
  6848. var _glIsShader = (shader) => {
  6849. var s = GL.shaders[shader];
  6850. if (!s) return 0;
  6851. return GLctx.isShader(s);
  6852. };
  6853. var _emscripten_glIsShader = _glIsShader;
  6854. /** @suppress {duplicate } */
  6855. var _glIsTexture = (id) => {
  6856. var texture = GL.textures[id];
  6857. if (!texture) return 0;
  6858. return GLctx.isTexture(texture);
  6859. };
  6860. var _emscripten_glIsTexture = _glIsTexture;
  6861. /** @suppress {duplicate } */
  6862. var _glIsVertexArray = (array) => {
  6863. var vao = GL.vaos[array];
  6864. if (!vao) return 0;
  6865. return GLctx.isVertexArray(vao);
  6866. };
  6867. /** @suppress {duplicate } */
  6868. var _glIsVertexArrayOES = _glIsVertexArray;
  6869. var _emscripten_glIsVertexArrayOES = _glIsVertexArrayOES;
  6870. /** @suppress {duplicate } */
  6871. var _glLineWidth = (x0) => GLctx.lineWidth(x0);
  6872. var _emscripten_glLineWidth = _glLineWidth;
  6873. /** @suppress {duplicate } */
  6874. var _glLinkProgram = (program) => {
  6875. program = GL.programs[program];
  6876. GLctx.linkProgram(program);
  6877. // Invalidate earlier computed uniform->ID mappings, those have now become stale
  6878. program.uniformLocsById = 0; // Mark as null-like so that glGetUniformLocation() knows to populate this again.
  6879. program.uniformSizeAndIdsByName = {};
  6880. };
  6881. var _emscripten_glLinkProgram = _glLinkProgram;
  6882. /** @suppress {duplicate } */
  6883. var _glPixelStorei = (pname, param) => {
  6884. if (pname == 3317) {
  6885. GL.unpackAlignment = param;
  6886. } else if (pname == 3314) {
  6887. GL.unpackRowLength = param;
  6888. }
  6889. GLctx.pixelStorei(pname, param);
  6890. };
  6891. var _emscripten_glPixelStorei = _glPixelStorei;
  6892. /** @suppress {duplicate } */
  6893. var _glPolygonModeWEBGL = (face, mode) => {
  6894. GLctx.webglPolygonMode['polygonModeWEBGL'](face, mode);
  6895. };
  6896. var _emscripten_glPolygonModeWEBGL = _glPolygonModeWEBGL;
  6897. /** @suppress {duplicate } */
  6898. var _glPolygonOffset = (x0, x1) => GLctx.polygonOffset(x0, x1);
  6899. var _emscripten_glPolygonOffset = _glPolygonOffset;
  6900. /** @suppress {duplicate } */
  6901. var _glPolygonOffsetClampEXT = (factor, units, clamp) => {
  6902. GLctx.extPolygonOffsetClamp['polygonOffsetClampEXT'](factor, units, clamp);
  6903. };
  6904. var _emscripten_glPolygonOffsetClampEXT = _glPolygonOffsetClampEXT;
  6905. /** @suppress {duplicate } */
  6906. var _glQueryCounterEXT = (id, target) => {
  6907. GLctx.disjointTimerQueryExt['queryCounterEXT'](GL.queries[id], target);
  6908. };
  6909. var _emscripten_glQueryCounterEXT = _glQueryCounterEXT;
  6910. var computeUnpackAlignedImageSize = (width, height, sizePerPixel) => {
  6911. function roundedToNextMultipleOf(x, y) {
  6912. return (x + y - 1) & -y;
  6913. }
  6914. var plainRowSize = (GL.unpackRowLength || width) * sizePerPixel;
  6915. var alignedRowSize = roundedToNextMultipleOf(plainRowSize, GL.unpackAlignment);
  6916. return height * alignedRowSize;
  6917. };
  6918. var colorChannelsInGlTextureFormat = (format) => {
  6919. // Micro-optimizations for size: map format to size by subtracting smallest
  6920. // enum value (0x1902) from all values first. Also omit the most common
  6921. // size value (1) from the list, which is assumed by formats not on the
  6922. // list.
  6923. var colorChannels = {
  6924. // 0x1902 /* GL_DEPTH_COMPONENT */ - 0x1902: 1,
  6925. // 0x1906 /* GL_ALPHA */ - 0x1902: 1,
  6926. 5: 3,
  6927. 6: 4,
  6928. // 0x1909 /* GL_LUMINANCE */ - 0x1902: 1,
  6929. 8: 2,
  6930. 29502: 3,
  6931. 29504: 4,
  6932. };
  6933. return colorChannels[format - 0x1902]||1;
  6934. };
  6935. var heapObjectForWebGLType = (type) => {
  6936. // Micro-optimization for size: Subtract lowest GL enum number (0x1400/* GL_BYTE */) from type to compare
  6937. // smaller values for the heap, for shorter generated code size.
  6938. // Also the type HEAPU16 is not tested for explicitly, but any unrecognized type will return out HEAPU16.
  6939. // (since most types are HEAPU16)
  6940. type -= 0x1400;
  6941. if (type == 1) return HEAPU8;
  6942. if (type == 4) return HEAP32;
  6943. if (type == 6) return HEAPF32;
  6944. if (type == 5
  6945. || type == 28922
  6946. )
  6947. return HEAPU32;
  6948. return HEAPU16;
  6949. };
  6950. var toTypedArrayIndex = (pointer, heap) =>
  6951. pointer >>> (31 - Math.clz32(heap.BYTES_PER_ELEMENT));
  6952. var emscriptenWebGLGetTexPixelData = (type, format, width, height, pixels, internalFormat) => {
  6953. var heap = heapObjectForWebGLType(type);
  6954. var sizePerPixel = colorChannelsInGlTextureFormat(format) * heap.BYTES_PER_ELEMENT;
  6955. var bytes = computeUnpackAlignedImageSize(width, height, sizePerPixel);
  6956. return heap.subarray(toTypedArrayIndex(pixels, heap), toTypedArrayIndex(pixels + bytes, heap));
  6957. };
  6958. /** @suppress {duplicate } */
  6959. var _glReadPixels = (x, y, width, height, format, type, pixels) => {
  6960. var pixelData = emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, format);
  6961. if (!pixelData) {
  6962. GL.recordError(0x500/*GL_INVALID_ENUM*/);
  6963. return;
  6964. }
  6965. GLctx.readPixels(x, y, width, height, format, type, pixelData);
  6966. };
  6967. var _emscripten_glReadPixels = _glReadPixels;
  6968. /** @suppress {duplicate } */
  6969. var _glReleaseShaderCompiler = () => {
  6970. // NOP (as allowed by GLES 2.0 spec)
  6971. };
  6972. var _emscripten_glReleaseShaderCompiler = _glReleaseShaderCompiler;
  6973. /** @suppress {duplicate } */
  6974. var _glRenderbufferStorage = (x0, x1, x2, x3) => GLctx.renderbufferStorage(x0, x1, x2, x3);
  6975. var _emscripten_glRenderbufferStorage = _glRenderbufferStorage;
  6976. /** @suppress {duplicate } */
  6977. var _glSampleCoverage = (value, invert) => {
  6978. GLctx.sampleCoverage(value, !!invert);
  6979. };
  6980. var _emscripten_glSampleCoverage = _glSampleCoverage;
  6981. /** @suppress {duplicate } */
  6982. var _glScissor = (x0, x1, x2, x3) => GLctx.scissor(x0, x1, x2, x3);
  6983. var _emscripten_glScissor = _glScissor;
  6984. /** @suppress {duplicate } */
  6985. var _glShaderBinary = (count, shaders, binaryformat, binary, length) => {
  6986. GL.recordError(0x500/*GL_INVALID_ENUM*/);
  6987. };
  6988. var _emscripten_glShaderBinary = _glShaderBinary;
  6989. /** @suppress {duplicate } */
  6990. var _glShaderSource = (shader, count, string, length) => {
  6991. var source = GL.getSource(shader, count, string, length);
  6992. GLctx.shaderSource(GL.shaders[shader], source);
  6993. };
  6994. var _emscripten_glShaderSource = _glShaderSource;
  6995. /** @suppress {duplicate } */
  6996. var _glStencilFunc = (x0, x1, x2) => GLctx.stencilFunc(x0, x1, x2);
  6997. var _emscripten_glStencilFunc = _glStencilFunc;
  6998. /** @suppress {duplicate } */
  6999. var _glStencilFuncSeparate = (x0, x1, x2, x3) => GLctx.stencilFuncSeparate(x0, x1, x2, x3);
  7000. var _emscripten_glStencilFuncSeparate = _glStencilFuncSeparate;
  7001. /** @suppress {duplicate } */
  7002. var _glStencilMask = (x0) => GLctx.stencilMask(x0);
  7003. var _emscripten_glStencilMask = _glStencilMask;
  7004. /** @suppress {duplicate } */
  7005. var _glStencilMaskSeparate = (x0, x1) => GLctx.stencilMaskSeparate(x0, x1);
  7006. var _emscripten_glStencilMaskSeparate = _glStencilMaskSeparate;
  7007. /** @suppress {duplicate } */
  7008. var _glStencilOp = (x0, x1, x2) => GLctx.stencilOp(x0, x1, x2);
  7009. var _emscripten_glStencilOp = _glStencilOp;
  7010. /** @suppress {duplicate } */
  7011. var _glStencilOpSeparate = (x0, x1, x2, x3) => GLctx.stencilOpSeparate(x0, x1, x2, x3);
  7012. var _emscripten_glStencilOpSeparate = _glStencilOpSeparate;
  7013. /** @suppress {duplicate } */
  7014. var _glTexImage2D = (target, level, internalFormat, width, height, border, format, type, pixels) => {
  7015. var pixelData = pixels ? emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, internalFormat) : null;
  7016. GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, pixelData);
  7017. };
  7018. var _emscripten_glTexImage2D = _glTexImage2D;
  7019. /** @suppress {duplicate } */
  7020. var _glTexParameterf = (x0, x1, x2) => GLctx.texParameterf(x0, x1, x2);
  7021. var _emscripten_glTexParameterf = _glTexParameterf;
  7022. /** @suppress {duplicate } */
  7023. var _glTexParameterfv = (target, pname, params) => {
  7024. var param = HEAPF32[((params)>>2)];
  7025. GLctx.texParameterf(target, pname, param);
  7026. };
  7027. var _emscripten_glTexParameterfv = _glTexParameterfv;
  7028. /** @suppress {duplicate } */
  7029. var _glTexParameteri = (x0, x1, x2) => GLctx.texParameteri(x0, x1, x2);
  7030. var _emscripten_glTexParameteri = _glTexParameteri;
  7031. /** @suppress {duplicate } */
  7032. var _glTexParameteriv = (target, pname, params) => {
  7033. var param = HEAP32[((params)>>2)];
  7034. GLctx.texParameteri(target, pname, param);
  7035. };
  7036. var _emscripten_glTexParameteriv = _glTexParameteriv;
  7037. /** @suppress {duplicate } */
  7038. var _glTexSubImage2D = (target, level, xoffset, yoffset, width, height, format, type, pixels) => {
  7039. var pixelData = pixels ? emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, 0) : null;
  7040. GLctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixelData);
  7041. };
  7042. var _emscripten_glTexSubImage2D = _glTexSubImage2D;
  7043. /** @suppress {duplicate } */
  7044. var _glUniform1f = (location, v0) => {
  7045. GLctx.uniform1f(webglGetUniformLocation(location), v0);
  7046. };
  7047. var _emscripten_glUniform1f = _glUniform1f;
  7048. var miniTempWebGLFloatBuffers = [];
  7049. /** @suppress {duplicate } */
  7050. var _glUniform1fv = (location, count, value) => {
  7051. if (count <= 288) {
  7052. // avoid allocation when uploading few enough uniforms
  7053. var view = miniTempWebGLFloatBuffers[count];
  7054. for (var i = 0; i < count; ++i) {
  7055. view[i] = HEAPF32[(((value)+(4*i))>>2)];
  7056. }
  7057. } else
  7058. {
  7059. var view = HEAPF32.subarray((((value)>>2)), ((value+count*4)>>2));
  7060. }
  7061. GLctx.uniform1fv(webglGetUniformLocation(location), view);
  7062. };
  7063. var _emscripten_glUniform1fv = _glUniform1fv;
  7064. /** @suppress {duplicate } */
  7065. var _glUniform1i = (location, v0) => {
  7066. GLctx.uniform1i(webglGetUniformLocation(location), v0);
  7067. };
  7068. var _emscripten_glUniform1i = _glUniform1i;
  7069. var miniTempWebGLIntBuffers = [];
  7070. /** @suppress {duplicate } */
  7071. var _glUniform1iv = (location, count, value) => {
  7072. if (count <= 288) {
  7073. // avoid allocation when uploading few enough uniforms
  7074. var view = miniTempWebGLIntBuffers[count];
  7075. for (var i = 0; i < count; ++i) {
  7076. view[i] = HEAP32[(((value)+(4*i))>>2)];
  7077. }
  7078. } else
  7079. {
  7080. var view = HEAP32.subarray((((value)>>2)), ((value+count*4)>>2));
  7081. }
  7082. GLctx.uniform1iv(webglGetUniformLocation(location), view);
  7083. };
  7084. var _emscripten_glUniform1iv = _glUniform1iv;
  7085. /** @suppress {duplicate } */
  7086. var _glUniform2f = (location, v0, v1) => {
  7087. GLctx.uniform2f(webglGetUniformLocation(location), v0, v1);
  7088. };
  7089. var _emscripten_glUniform2f = _glUniform2f;
  7090. /** @suppress {duplicate } */
  7091. var _glUniform2fv = (location, count, value) => {
  7092. if (count <= 144) {
  7093. // avoid allocation when uploading few enough uniforms
  7094. count *= 2;
  7095. var view = miniTempWebGLFloatBuffers[count];
  7096. for (var i = 0; i < count; i += 2) {
  7097. view[i] = HEAPF32[(((value)+(4*i))>>2)];
  7098. view[i+1] = HEAPF32[(((value)+(4*i+4))>>2)];
  7099. }
  7100. } else
  7101. {
  7102. var view = HEAPF32.subarray((((value)>>2)), ((value+count*8)>>2));
  7103. }
  7104. GLctx.uniform2fv(webglGetUniformLocation(location), view);
  7105. };
  7106. var _emscripten_glUniform2fv = _glUniform2fv;
  7107. /** @suppress {duplicate } */
  7108. var _glUniform2i = (location, v0, v1) => {
  7109. GLctx.uniform2i(webglGetUniformLocation(location), v0, v1);
  7110. };
  7111. var _emscripten_glUniform2i = _glUniform2i;
  7112. /** @suppress {duplicate } */
  7113. var _glUniform2iv = (location, count, value) => {
  7114. if (count <= 144) {
  7115. // avoid allocation when uploading few enough uniforms
  7116. count *= 2;
  7117. var view = miniTempWebGLIntBuffers[count];
  7118. for (var i = 0; i < count; i += 2) {
  7119. view[i] = HEAP32[(((value)+(4*i))>>2)];
  7120. view[i+1] = HEAP32[(((value)+(4*i+4))>>2)];
  7121. }
  7122. } else
  7123. {
  7124. var view = HEAP32.subarray((((value)>>2)), ((value+count*8)>>2));
  7125. }
  7126. GLctx.uniform2iv(webglGetUniformLocation(location), view);
  7127. };
  7128. var _emscripten_glUniform2iv = _glUniform2iv;
  7129. /** @suppress {duplicate } */
  7130. var _glUniform3f = (location, v0, v1, v2) => {
  7131. GLctx.uniform3f(webglGetUniformLocation(location), v0, v1, v2);
  7132. };
  7133. var _emscripten_glUniform3f = _glUniform3f;
  7134. /** @suppress {duplicate } */
  7135. var _glUniform3fv = (location, count, value) => {
  7136. if (count <= 96) {
  7137. // avoid allocation when uploading few enough uniforms
  7138. count *= 3;
  7139. var view = miniTempWebGLFloatBuffers[count];
  7140. for (var i = 0; i < count; i += 3) {
  7141. view[i] = HEAPF32[(((value)+(4*i))>>2)];
  7142. view[i+1] = HEAPF32[(((value)+(4*i+4))>>2)];
  7143. view[i+2] = HEAPF32[(((value)+(4*i+8))>>2)];
  7144. }
  7145. } else
  7146. {
  7147. var view = HEAPF32.subarray((((value)>>2)), ((value+count*12)>>2));
  7148. }
  7149. GLctx.uniform3fv(webglGetUniformLocation(location), view);
  7150. };
  7151. var _emscripten_glUniform3fv = _glUniform3fv;
  7152. /** @suppress {duplicate } */
  7153. var _glUniform3i = (location, v0, v1, v2) => {
  7154. GLctx.uniform3i(webglGetUniformLocation(location), v0, v1, v2);
  7155. };
  7156. var _emscripten_glUniform3i = _glUniform3i;
  7157. /** @suppress {duplicate } */
  7158. var _glUniform3iv = (location, count, value) => {
  7159. if (count <= 96) {
  7160. // avoid allocation when uploading few enough uniforms
  7161. count *= 3;
  7162. var view = miniTempWebGLIntBuffers[count];
  7163. for (var i = 0; i < count; i += 3) {
  7164. view[i] = HEAP32[(((value)+(4*i))>>2)];
  7165. view[i+1] = HEAP32[(((value)+(4*i+4))>>2)];
  7166. view[i+2] = HEAP32[(((value)+(4*i+8))>>2)];
  7167. }
  7168. } else
  7169. {
  7170. var view = HEAP32.subarray((((value)>>2)), ((value+count*12)>>2));
  7171. }
  7172. GLctx.uniform3iv(webglGetUniformLocation(location), view);
  7173. };
  7174. var _emscripten_glUniform3iv = _glUniform3iv;
  7175. /** @suppress {duplicate } */
  7176. var _glUniform4f = (location, v0, v1, v2, v3) => {
  7177. GLctx.uniform4f(webglGetUniformLocation(location), v0, v1, v2, v3);
  7178. };
  7179. var _emscripten_glUniform4f = _glUniform4f;
  7180. /** @suppress {duplicate } */
  7181. var _glUniform4fv = (location, count, value) => {
  7182. if (count <= 72) {
  7183. // avoid allocation when uploading few enough uniforms
  7184. var view = miniTempWebGLFloatBuffers[4*count];
  7185. // hoist the heap out of the loop for size and for pthreads+growth.
  7186. var heap = HEAPF32;
  7187. value = ((value)>>2);
  7188. count *= 4;
  7189. for (var i = 0; i < count; i += 4) {
  7190. var dst = value + i;
  7191. view[i] = heap[dst];
  7192. view[i + 1] = heap[dst + 1];
  7193. view[i + 2] = heap[dst + 2];
  7194. view[i + 3] = heap[dst + 3];
  7195. }
  7196. } else
  7197. {
  7198. var view = HEAPF32.subarray((((value)>>2)), ((value+count*16)>>2));
  7199. }
  7200. GLctx.uniform4fv(webglGetUniformLocation(location), view);
  7201. };
  7202. var _emscripten_glUniform4fv = _glUniform4fv;
  7203. /** @suppress {duplicate } */
  7204. var _glUniform4i = (location, v0, v1, v2, v3) => {
  7205. GLctx.uniform4i(webglGetUniformLocation(location), v0, v1, v2, v3);
  7206. };
  7207. var _emscripten_glUniform4i = _glUniform4i;
  7208. /** @suppress {duplicate } */
  7209. var _glUniform4iv = (location, count, value) => {
  7210. if (count <= 72) {
  7211. // avoid allocation when uploading few enough uniforms
  7212. count *= 4;
  7213. var view = miniTempWebGLIntBuffers[count];
  7214. for (var i = 0; i < count; i += 4) {
  7215. view[i] = HEAP32[(((value)+(4*i))>>2)];
  7216. view[i+1] = HEAP32[(((value)+(4*i+4))>>2)];
  7217. view[i+2] = HEAP32[(((value)+(4*i+8))>>2)];
  7218. view[i+3] = HEAP32[(((value)+(4*i+12))>>2)];
  7219. }
  7220. } else
  7221. {
  7222. var view = HEAP32.subarray((((value)>>2)), ((value+count*16)>>2));
  7223. }
  7224. GLctx.uniform4iv(webglGetUniformLocation(location), view);
  7225. };
  7226. var _emscripten_glUniform4iv = _glUniform4iv;
  7227. /** @suppress {duplicate } */
  7228. var _glUniformMatrix2fv = (location, count, transpose, value) => {
  7229. if (count <= 72) {
  7230. // avoid allocation when uploading few enough uniforms
  7231. count *= 4;
  7232. var view = miniTempWebGLFloatBuffers[count];
  7233. for (var i = 0; i < count; i += 4) {
  7234. view[i] = HEAPF32[(((value)+(4*i))>>2)];
  7235. view[i+1] = HEAPF32[(((value)+(4*i+4))>>2)];
  7236. view[i+2] = HEAPF32[(((value)+(4*i+8))>>2)];
  7237. view[i+3] = HEAPF32[(((value)+(4*i+12))>>2)];
  7238. }
  7239. } else
  7240. {
  7241. var view = HEAPF32.subarray((((value)>>2)), ((value+count*16)>>2));
  7242. }
  7243. GLctx.uniformMatrix2fv(webglGetUniformLocation(location), !!transpose, view);
  7244. };
  7245. var _emscripten_glUniformMatrix2fv = _glUniformMatrix2fv;
  7246. /** @suppress {duplicate } */
  7247. var _glUniformMatrix3fv = (location, count, transpose, value) => {
  7248. if (count <= 32) {
  7249. // avoid allocation when uploading few enough uniforms
  7250. count *= 9;
  7251. var view = miniTempWebGLFloatBuffers[count];
  7252. for (var i = 0; i < count; i += 9) {
  7253. view[i] = HEAPF32[(((value)+(4*i))>>2)];
  7254. view[i+1] = HEAPF32[(((value)+(4*i+4))>>2)];
  7255. view[i+2] = HEAPF32[(((value)+(4*i+8))>>2)];
  7256. view[i+3] = HEAPF32[(((value)+(4*i+12))>>2)];
  7257. view[i+4] = HEAPF32[(((value)+(4*i+16))>>2)];
  7258. view[i+5] = HEAPF32[(((value)+(4*i+20))>>2)];
  7259. view[i+6] = HEAPF32[(((value)+(4*i+24))>>2)];
  7260. view[i+7] = HEAPF32[(((value)+(4*i+28))>>2)];
  7261. view[i+8] = HEAPF32[(((value)+(4*i+32))>>2)];
  7262. }
  7263. } else
  7264. {
  7265. var view = HEAPF32.subarray((((value)>>2)), ((value+count*36)>>2));
  7266. }
  7267. GLctx.uniformMatrix3fv(webglGetUniformLocation(location), !!transpose, view);
  7268. };
  7269. var _emscripten_glUniformMatrix3fv = _glUniformMatrix3fv;
  7270. /** @suppress {duplicate } */
  7271. var _glUniformMatrix4fv = (location, count, transpose, value) => {
  7272. if (count <= 18) {
  7273. // avoid allocation when uploading few enough uniforms
  7274. var view = miniTempWebGLFloatBuffers[16*count];
  7275. // hoist the heap out of the loop for size and for pthreads+growth.
  7276. var heap = HEAPF32;
  7277. value = ((value)>>2);
  7278. count *= 16;
  7279. for (var i = 0; i < count; i += 16) {
  7280. var dst = value + i;
  7281. view[i] = heap[dst];
  7282. view[i + 1] = heap[dst + 1];
  7283. view[i + 2] = heap[dst + 2];
  7284. view[i + 3] = heap[dst + 3];
  7285. view[i + 4] = heap[dst + 4];
  7286. view[i + 5] = heap[dst + 5];
  7287. view[i + 6] = heap[dst + 6];
  7288. view[i + 7] = heap[dst + 7];
  7289. view[i + 8] = heap[dst + 8];
  7290. view[i + 9] = heap[dst + 9];
  7291. view[i + 10] = heap[dst + 10];
  7292. view[i + 11] = heap[dst + 11];
  7293. view[i + 12] = heap[dst + 12];
  7294. view[i + 13] = heap[dst + 13];
  7295. view[i + 14] = heap[dst + 14];
  7296. view[i + 15] = heap[dst + 15];
  7297. }
  7298. } else
  7299. {
  7300. var view = HEAPF32.subarray((((value)>>2)), ((value+count*64)>>2));
  7301. }
  7302. GLctx.uniformMatrix4fv(webglGetUniformLocation(location), !!transpose, view);
  7303. };
  7304. var _emscripten_glUniformMatrix4fv = _glUniformMatrix4fv;
  7305. /** @suppress {duplicate } */
  7306. var _glUseProgram = (program) => {
  7307. program = GL.programs[program];
  7308. GLctx.useProgram(program);
  7309. // Record the currently active program so that we can access the uniform
  7310. // mapping table of that program.
  7311. GLctx.currentProgram = program;
  7312. };
  7313. var _emscripten_glUseProgram = _glUseProgram;
  7314. /** @suppress {duplicate } */
  7315. var _glValidateProgram = (program) => {
  7316. GLctx.validateProgram(GL.programs[program]);
  7317. };
  7318. var _emscripten_glValidateProgram = _glValidateProgram;
  7319. /** @suppress {duplicate } */
  7320. var _glVertexAttrib1f = (x0, x1) => GLctx.vertexAttrib1f(x0, x1);
  7321. var _emscripten_glVertexAttrib1f = _glVertexAttrib1f;
  7322. /** @suppress {duplicate } */
  7323. var _glVertexAttrib1fv = (index, v) => {
  7324. GLctx.vertexAttrib1f(index, HEAPF32[v>>2]);
  7325. };
  7326. var _emscripten_glVertexAttrib1fv = _glVertexAttrib1fv;
  7327. /** @suppress {duplicate } */
  7328. var _glVertexAttrib2f = (x0, x1, x2) => GLctx.vertexAttrib2f(x0, x1, x2);
  7329. var _emscripten_glVertexAttrib2f = _glVertexAttrib2f;
  7330. /** @suppress {duplicate } */
  7331. var _glVertexAttrib2fv = (index, v) => {
  7332. GLctx.vertexAttrib2f(index, HEAPF32[v>>2], HEAPF32[v+4>>2]);
  7333. };
  7334. var _emscripten_glVertexAttrib2fv = _glVertexAttrib2fv;
  7335. /** @suppress {duplicate } */
  7336. var _glVertexAttrib3f = (x0, x1, x2, x3) => GLctx.vertexAttrib3f(x0, x1, x2, x3);
  7337. var _emscripten_glVertexAttrib3f = _glVertexAttrib3f;
  7338. /** @suppress {duplicate } */
  7339. var _glVertexAttrib3fv = (index, v) => {
  7340. GLctx.vertexAttrib3f(index, HEAPF32[v>>2], HEAPF32[v+4>>2], HEAPF32[v+8>>2]);
  7341. };
  7342. var _emscripten_glVertexAttrib3fv = _glVertexAttrib3fv;
  7343. /** @suppress {duplicate } */
  7344. var _glVertexAttrib4f = (x0, x1, x2, x3, x4) => GLctx.vertexAttrib4f(x0, x1, x2, x3, x4);
  7345. var _emscripten_glVertexAttrib4f = _glVertexAttrib4f;
  7346. /** @suppress {duplicate } */
  7347. var _glVertexAttrib4fv = (index, v) => {
  7348. GLctx.vertexAttrib4f(index, HEAPF32[v>>2], HEAPF32[v+4>>2], HEAPF32[v+8>>2], HEAPF32[v+12>>2]);
  7349. };
  7350. var _emscripten_glVertexAttrib4fv = _glVertexAttrib4fv;
  7351. /** @suppress {duplicate } */
  7352. var _glVertexAttribDivisor = (index, divisor) => {
  7353. GLctx.vertexAttribDivisor(index, divisor);
  7354. };
  7355. /** @suppress {duplicate } */
  7356. var _glVertexAttribDivisorANGLE = _glVertexAttribDivisor;
  7357. var _emscripten_glVertexAttribDivisorANGLE = _glVertexAttribDivisorANGLE;
  7358. /** @suppress {duplicate } */
  7359. var _glVertexAttribPointer = (index, size, type, normalized, stride, ptr) => {
  7360. GLctx.vertexAttribPointer(index, size, type, !!normalized, stride, ptr);
  7361. };
  7362. var _emscripten_glVertexAttribPointer = _glVertexAttribPointer;
  7363. /** @suppress {duplicate } */
  7364. var _glViewport = (x0, x1, x2, x3) => GLctx.viewport(x0, x1, x2, x3);
  7365. var _emscripten_glViewport = _glViewport;
  7366. var _emscripten_has_asyncify = () => 0;
  7367. var doRequestFullscreen = (target, strategy) => {
  7368. if (!JSEvents.fullscreenEnabled()) return -1;
  7369. target = findEventTarget(target);
  7370. if (!target) return -4;
  7371. if (!target.requestFullscreen
  7372. && !target.webkitRequestFullscreen
  7373. ) {
  7374. return -3;
  7375. }
  7376. // Queue this function call if we're not currently in an event handler and
  7377. // the user saw it appropriate to do so.
  7378. if (!JSEvents.canPerformEventHandlerRequests()) {
  7379. if (strategy.deferUntilInEventHandler) {
  7380. JSEvents.deferCall(JSEvents_requestFullscreen, 1 /* priority over pointer lock */, [target, strategy]);
  7381. return 1;
  7382. }
  7383. return -2;
  7384. }
  7385. return JSEvents_requestFullscreen(target, strategy);
  7386. };
  7387. var _emscripten_request_fullscreen_strategy = (target, deferUntilInEventHandler, fullscreenStrategy) => {
  7388. var strategy = {
  7389. scaleMode: HEAP32[((fullscreenStrategy)>>2)],
  7390. canvasResolutionScaleMode: HEAP32[(((fullscreenStrategy)+(4))>>2)],
  7391. filteringMode: HEAP32[(((fullscreenStrategy)+(8))>>2)],
  7392. deferUntilInEventHandler,
  7393. canvasResizedCallback: HEAP32[(((fullscreenStrategy)+(12))>>2)],
  7394. canvasResizedCallbackUserData: HEAP32[(((fullscreenStrategy)+(16))>>2)]
  7395. };
  7396. return doRequestFullscreen(target, strategy);
  7397. };
  7398. var _emscripten_request_pointerlock = (target, deferUntilInEventHandler) => {
  7399. target = findEventTarget(target);
  7400. if (!target) return -4;
  7401. if (!target.requestPointerLock
  7402. ) {
  7403. return -1;
  7404. }
  7405. // Queue this function call if we're not currently in an event handler and
  7406. // the user saw it appropriate to do so.
  7407. if (!JSEvents.canPerformEventHandlerRequests()) {
  7408. if (deferUntilInEventHandler) {
  7409. JSEvents.deferCall(requestPointerLock, 2 /* priority below fullscreen */, [target]);
  7410. return 1;
  7411. }
  7412. return -2;
  7413. }
  7414. return requestPointerLock(target);
  7415. };
  7416. var getHeapMax = () =>
  7417. // Stay one Wasm page short of 4GB: while e.g. Chrome is able to allocate
  7418. // full 4GB Wasm memories, the size will wrap back to 0 bytes in Wasm side
  7419. // for any code that deals with heap sizes, which would require special
  7420. // casing all heap size related code to treat 0 specially.
  7421. 2147483648;
  7422. var growMemory = (size) => {
  7423. var b = wasmMemory.buffer;
  7424. var pages = ((size - b.byteLength + 65535) / 65536) | 0;
  7425. try {
  7426. // round size grow request up to wasm page size (fixed 64KB per spec)
  7427. wasmMemory.grow(pages); // .grow() takes a delta compared to the previous size
  7428. updateMemoryViews();
  7429. return 1 /*success*/;
  7430. } catch(e) {
  7431. err(`growMemory: Attempted to grow heap from ${b.byteLength} bytes to ${size} bytes, but got error: ${e}`);
  7432. }
  7433. // implicit 0 return to save code size (caller will cast "undefined" into 0
  7434. // anyhow)
  7435. };
  7436. var _emscripten_resize_heap = (requestedSize) => {
  7437. var oldSize = HEAPU8.length;
  7438. // With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned.
  7439. requestedSize >>>= 0;
  7440. // With multithreaded builds, races can happen (another thread might increase the size
  7441. // in between), so return a failure, and let the caller retry.
  7442. assert(requestedSize > oldSize);
  7443. // Memory resize rules:
  7444. // 1. Always increase heap size to at least the requested size, rounded up
  7445. // to next page multiple.
  7446. // 2a. If MEMORY_GROWTH_LINEAR_STEP == -1, excessively resize the heap
  7447. // geometrically: increase the heap size according to
  7448. // MEMORY_GROWTH_GEOMETRIC_STEP factor (default +20%), At most
  7449. // overreserve by MEMORY_GROWTH_GEOMETRIC_CAP bytes (default 96MB).
  7450. // 2b. If MEMORY_GROWTH_LINEAR_STEP != -1, excessively resize the heap
  7451. // linearly: increase the heap size by at least
  7452. // MEMORY_GROWTH_LINEAR_STEP bytes.
  7453. // 3. Max size for the heap is capped at 2048MB-WASM_PAGE_SIZE, or by
  7454. // MAXIMUM_MEMORY, or by ASAN limit, depending on which is smallest
  7455. // 4. If we were unable to allocate as much memory, it may be due to
  7456. // over-eager decision to excessively reserve due to (3) above.
  7457. // Hence if an allocation fails, cut down on the amount of excess
  7458. // growth, in an attempt to succeed to perform a smaller allocation.
  7459. // A limit is set for how much we can grow. We should not exceed that
  7460. // (the wasm binary specifies it, so if we tried, we'd fail anyhow).
  7461. var maxHeapSize = getHeapMax();
  7462. if (requestedSize > maxHeapSize) {
  7463. err(`Cannot enlarge memory, requested ${requestedSize} bytes, but the limit is ${maxHeapSize} bytes!`);
  7464. return false;
  7465. }
  7466. // Loop through potential heap size increases. If we attempt a too eager
  7467. // reservation that fails, cut down on the attempted size and reserve a
  7468. // smaller bump instead. (max 3 times, chosen somewhat arbitrarily)
  7469. for (var cutDown = 1; cutDown <= 4; cutDown *= 2) {
  7470. var overGrownHeapSize = oldSize * (1 + 0.2 / cutDown); // ensure geometric growth
  7471. // but limit overreserving (default to capping at +96MB overgrowth at most)
  7472. overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296 );
  7473. var newSize = Math.min(maxHeapSize, alignMemory(Math.max(requestedSize, overGrownHeapSize), 65536));
  7474. var replacement = growMemory(newSize);
  7475. if (replacement) {
  7476. return true;
  7477. }
  7478. }
  7479. err(`Failed to grow the heap from ${oldSize} bytes to ${newSize} bytes, not enough memory!`);
  7480. return false;
  7481. };
  7482. /** @suppress {checkTypes} */
  7483. var _emscripten_sample_gamepad_data = () => {
  7484. try {
  7485. if (navigator.getGamepads) return (JSEvents.lastGamepadState = navigator.getGamepads())
  7486. ? 0 : -1;
  7487. } catch(e) {
  7488. err(`navigator.getGamepads() exists, but failed to execute with exception ${e}. Disabling Gamepad access.`);
  7489. navigator.getGamepads = null; // Disable getGamepads() so that it won't be attempted to be used again.
  7490. }
  7491. return -1;
  7492. };
  7493. var registerBeforeUnloadEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString) => {
  7494. var beforeUnloadEventHandlerFunc = (e = event) => {
  7495. // Note: This is always called on the main browser thread, since it needs synchronously return a value!
  7496. var confirmationMessage = getWasmTableEntry(callbackfunc)(eventTypeId, 0, userData);
  7497. if (confirmationMessage) {
  7498. confirmationMessage = UTF8ToString(confirmationMessage);
  7499. }
  7500. if (confirmationMessage) {
  7501. e.preventDefault();
  7502. e.returnValue = confirmationMessage;
  7503. return confirmationMessage;
  7504. }
  7505. };
  7506. var eventHandler = {
  7507. target: findEventTarget(target),
  7508. eventTypeString,
  7509. callbackfunc,
  7510. handlerFunc: beforeUnloadEventHandlerFunc,
  7511. useCapture
  7512. };
  7513. return JSEvents.registerOrRemoveHandler(eventHandler);
  7514. };
  7515. var _emscripten_set_beforeunload_callback_on_thread = (userData, callbackfunc, targetThread) => {
  7516. if (typeof onbeforeunload == 'undefined') return -1;
  7517. // beforeunload callback can only be registered on the main browser thread, because the page will go away immediately after returning from the handler,
  7518. // and there is no time to start proxying it anywhere.
  7519. if (targetThread !== 1) return -5;
  7520. return registerBeforeUnloadEventCallback(2, userData, true, callbackfunc, 28, "beforeunload");
  7521. };
  7522. var registerFocusEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  7523. JSEvents.focusEvent ||= _malloc(256);
  7524. var focusEventHandlerFunc = (e = event) => {
  7525. var nodeName = JSEvents.getNodeNameForTarget(e.target);
  7526. var id = e.target.id ? e.target.id : '';
  7527. var focusEvent = JSEvents.focusEvent;
  7528. stringToUTF8(nodeName, focusEvent + 0, 128);
  7529. stringToUTF8(id, focusEvent + 128, 128);
  7530. if (getWasmTableEntry(callbackfunc)(eventTypeId, focusEvent, userData)) e.preventDefault();
  7531. };
  7532. var eventHandler = {
  7533. target: findEventTarget(target),
  7534. eventTypeString,
  7535. callbackfunc,
  7536. handlerFunc: focusEventHandlerFunc,
  7537. useCapture
  7538. };
  7539. return JSEvents.registerOrRemoveHandler(eventHandler);
  7540. };
  7541. var _emscripten_set_blur_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7542. registerFocusEventCallback(target, userData, useCapture, callbackfunc, 12, "blur", targetThread);
  7543. var _emscripten_set_element_css_size = (target, width, height) => {
  7544. target = findEventTarget(target);
  7545. if (!target) return -4;
  7546. target.style.width = width + "px";
  7547. target.style.height = height + "px";
  7548. return 0;
  7549. };
  7550. var _emscripten_set_focus_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7551. registerFocusEventCallback(target, userData, useCapture, callbackfunc, 13, "focus", targetThread);
  7552. var fillFullscreenChangeEventData = (eventStruct) => {
  7553. var fullscreenElement = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement;
  7554. var isFullscreen = !!fullscreenElement;
  7555. // Assigning a boolean to HEAP32 with expected type coercion.
  7556. /** @suppress{checkTypes} */
  7557. HEAP8[eventStruct] = isFullscreen;
  7558. HEAP8[(eventStruct)+(1)] = JSEvents.fullscreenEnabled();
  7559. // If transitioning to fullscreen, report info about the element that is now fullscreen.
  7560. // If transitioning to windowed mode, report info about the element that just was fullscreen.
  7561. var reportedElement = isFullscreen ? fullscreenElement : JSEvents.previousFullscreenElement;
  7562. var nodeName = JSEvents.getNodeNameForTarget(reportedElement);
  7563. var id = reportedElement?.id || '';
  7564. stringToUTF8(nodeName, eventStruct + 2, 128);
  7565. stringToUTF8(id, eventStruct + 130, 128);
  7566. HEAP32[(((eventStruct)+(260))>>2)] = reportedElement ? reportedElement.clientWidth : 0;
  7567. HEAP32[(((eventStruct)+(264))>>2)] = reportedElement ? reportedElement.clientHeight : 0;
  7568. HEAP32[(((eventStruct)+(268))>>2)] = screen.width;
  7569. HEAP32[(((eventStruct)+(272))>>2)] = screen.height;
  7570. if (isFullscreen) {
  7571. JSEvents.previousFullscreenElement = fullscreenElement;
  7572. }
  7573. };
  7574. var registerFullscreenChangeEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  7575. JSEvents.fullscreenChangeEvent ||= _malloc(276);
  7576. var fullscreenChangeEventhandlerFunc = (e = event) => {
  7577. var fullscreenChangeEvent = JSEvents.fullscreenChangeEvent;
  7578. fillFullscreenChangeEventData(fullscreenChangeEvent);
  7579. if (getWasmTableEntry(callbackfunc)(eventTypeId, fullscreenChangeEvent, userData)) e.preventDefault();
  7580. };
  7581. var eventHandler = {
  7582. target,
  7583. eventTypeString,
  7584. callbackfunc,
  7585. handlerFunc: fullscreenChangeEventhandlerFunc,
  7586. useCapture
  7587. };
  7588. return JSEvents.registerOrRemoveHandler(eventHandler);
  7589. };
  7590. var _emscripten_set_fullscreenchange_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) => {
  7591. if (!JSEvents.fullscreenEnabled()) return -1;
  7592. target = findEventTarget(target);
  7593. if (!target) return -4;
  7594. // Unprefixed Fullscreen API shipped in Chromium 71 (https://bugs.chromium.org/p/chromium/issues/detail?id=383813)
  7595. // As of Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitfullscreenchange. TODO: revisit this check once Safari ships unprefixed version.
  7596. registerFullscreenChangeEventCallback(target, userData, useCapture, callbackfunc, 19, "webkitfullscreenchange", targetThread);
  7597. return registerFullscreenChangeEventCallback(target, userData, useCapture, callbackfunc, 19, "fullscreenchange", targetThread);
  7598. };
  7599. var registerGamepadEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  7600. JSEvents.gamepadEvent ||= _malloc(1240);
  7601. var gamepadEventHandlerFunc = (e = event) => {
  7602. var gamepadEvent = JSEvents.gamepadEvent;
  7603. fillGamepadEventData(gamepadEvent, e["gamepad"]);
  7604. if (getWasmTableEntry(callbackfunc)(eventTypeId, gamepadEvent, userData)) e.preventDefault();
  7605. };
  7606. var eventHandler = {
  7607. target: findEventTarget(target),
  7608. allowsDeferredCalls: true,
  7609. eventTypeString,
  7610. callbackfunc,
  7611. handlerFunc: gamepadEventHandlerFunc,
  7612. useCapture
  7613. };
  7614. return JSEvents.registerOrRemoveHandler(eventHandler);
  7615. };
  7616. var _emscripten_set_gamepadconnected_callback_on_thread = (userData, useCapture, callbackfunc, targetThread) => {
  7617. if (_emscripten_sample_gamepad_data()) return -1;
  7618. return registerGamepadEventCallback(2, userData, useCapture, callbackfunc, 26, "gamepadconnected", targetThread);
  7619. };
  7620. var _emscripten_set_gamepaddisconnected_callback_on_thread = (userData, useCapture, callbackfunc, targetThread) => {
  7621. if (_emscripten_sample_gamepad_data()) return -1;
  7622. return registerGamepadEventCallback(2, userData, useCapture, callbackfunc, 27, "gamepaddisconnected", targetThread);
  7623. };
  7624. var registerKeyEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  7625. JSEvents.keyEvent ||= _malloc(160);
  7626. var keyEventHandlerFunc = (e) => {
  7627. assert(e);
  7628. var keyEventData = JSEvents.keyEvent;
  7629. HEAPF64[((keyEventData)>>3)] = e.timeStamp;
  7630. var idx = ((keyEventData)>>2);
  7631. HEAP32[idx + 2] = e.location;
  7632. HEAP8[keyEventData + 12] = e.ctrlKey;
  7633. HEAP8[keyEventData + 13] = e.shiftKey;
  7634. HEAP8[keyEventData + 14] = e.altKey;
  7635. HEAP8[keyEventData + 15] = e.metaKey;
  7636. HEAP8[keyEventData + 16] = e.repeat;
  7637. HEAP32[idx + 5] = e.charCode;
  7638. HEAP32[idx + 6] = e.keyCode;
  7639. HEAP32[idx + 7] = e.which;
  7640. stringToUTF8(e.key || '', keyEventData + 32, 32);
  7641. stringToUTF8(e.code || '', keyEventData + 64, 32);
  7642. stringToUTF8(e.char || '', keyEventData + 96, 32);
  7643. stringToUTF8(e.locale || '', keyEventData + 128, 32);
  7644. if (getWasmTableEntry(callbackfunc)(eventTypeId, keyEventData, userData)) e.preventDefault();
  7645. };
  7646. var eventHandler = {
  7647. target: findEventTarget(target),
  7648. eventTypeString,
  7649. callbackfunc,
  7650. handlerFunc: keyEventHandlerFunc,
  7651. useCapture
  7652. };
  7653. return JSEvents.registerOrRemoveHandler(eventHandler);
  7654. };
  7655. var _emscripten_set_keydown_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7656. registerKeyEventCallback(target, userData, useCapture, callbackfunc, 2, "keydown", targetThread);
  7657. var _emscripten_set_keypress_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7658. registerKeyEventCallback(target, userData, useCapture, callbackfunc, 1, "keypress", targetThread);
  7659. var _emscripten_set_keyup_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7660. registerKeyEventCallback(target, userData, useCapture, callbackfunc, 3, "keyup", targetThread);
  7661. var _emscripten_set_main_loop = (func, fps, simulateInfiniteLoop) => {
  7662. var iterFunc = getWasmTableEntry(func);
  7663. setMainLoop(iterFunc, fps, simulateInfiniteLoop);
  7664. };
  7665. var fillMouseEventData = (eventStruct, e, target) => {
  7666. assert(eventStruct % 4 == 0);
  7667. HEAPF64[((eventStruct)>>3)] = e.timeStamp;
  7668. var idx = ((eventStruct)>>2);
  7669. HEAP32[idx + 2] = e.screenX;
  7670. HEAP32[idx + 3] = e.screenY;
  7671. HEAP32[idx + 4] = e.clientX;
  7672. HEAP32[idx + 5] = e.clientY;
  7673. HEAP8[eventStruct + 24] = e.ctrlKey;
  7674. HEAP8[eventStruct + 25] = e.shiftKey;
  7675. HEAP8[eventStruct + 26] = e.altKey;
  7676. HEAP8[eventStruct + 27] = e.metaKey;
  7677. HEAP16[idx*2 + 14] = e.button;
  7678. HEAP16[idx*2 + 15] = e.buttons;
  7679. HEAP32[idx + 8] = e["movementX"]
  7680. ;
  7681. HEAP32[idx + 9] = e["movementY"]
  7682. ;
  7683. // Note: rect contains doubles (truncated to placate SAFE_HEAP, which is the same behaviour when writing to HEAP32 anyway)
  7684. var rect = getBoundingClientRect(target);
  7685. HEAP32[idx + 10] = e.clientX - (rect.left | 0);
  7686. HEAP32[idx + 11] = e.clientY - (rect.top | 0);
  7687. };
  7688. var registerMouseEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  7689. JSEvents.mouseEvent ||= _malloc(64);
  7690. target = findEventTarget(target);
  7691. var mouseEventHandlerFunc = (e = event) => {
  7692. // TODO: Make this access thread safe, or this could update live while app is reading it.
  7693. fillMouseEventData(JSEvents.mouseEvent, e, target);
  7694. if (getWasmTableEntry(callbackfunc)(eventTypeId, JSEvents.mouseEvent, userData)) e.preventDefault();
  7695. };
  7696. var eventHandler = {
  7697. target,
  7698. allowsDeferredCalls: eventTypeString != 'mousemove' && eventTypeString != 'mouseenter' && eventTypeString != 'mouseleave', // Mouse move events do not allow fullscreen/pointer lock requests to be handled in them!
  7699. eventTypeString,
  7700. callbackfunc,
  7701. handlerFunc: mouseEventHandlerFunc,
  7702. useCapture
  7703. };
  7704. return JSEvents.registerOrRemoveHandler(eventHandler);
  7705. };
  7706. var _emscripten_set_mousedown_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7707. registerMouseEventCallback(target, userData, useCapture, callbackfunc, 5, "mousedown", targetThread);
  7708. var _emscripten_set_mouseenter_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7709. registerMouseEventCallback(target, userData, useCapture, callbackfunc, 33, "mouseenter", targetThread);
  7710. var _emscripten_set_mouseleave_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7711. registerMouseEventCallback(target, userData, useCapture, callbackfunc, 34, "mouseleave", targetThread);
  7712. var _emscripten_set_mousemove_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7713. registerMouseEventCallback(target, userData, useCapture, callbackfunc, 8, "mousemove", targetThread);
  7714. var _emscripten_set_mouseup_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7715. registerMouseEventCallback(target, userData, useCapture, callbackfunc, 6, "mouseup", targetThread);
  7716. var fillPointerlockChangeEventData = (eventStruct) => {
  7717. var pointerLockElement = document.pointerLockElement || document.mozPointerLockElement || document.webkitPointerLockElement || document.msPointerLockElement;
  7718. var isPointerlocked = !!pointerLockElement;
  7719. // Assigning a boolean to HEAP32 with expected type coercion.
  7720. /** @suppress{checkTypes} */
  7721. HEAP8[eventStruct] = isPointerlocked;
  7722. var nodeName = JSEvents.getNodeNameForTarget(pointerLockElement);
  7723. var id = pointerLockElement?.id || '';
  7724. stringToUTF8(nodeName, eventStruct + 1, 128);
  7725. stringToUTF8(id, eventStruct + 129, 128);
  7726. };
  7727. var registerPointerlockChangeEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  7728. JSEvents.pointerlockChangeEvent ||= _malloc(257);
  7729. var pointerlockChangeEventHandlerFunc = (e = event) => {
  7730. var pointerlockChangeEvent = JSEvents.pointerlockChangeEvent;
  7731. fillPointerlockChangeEventData(pointerlockChangeEvent);
  7732. if (getWasmTableEntry(callbackfunc)(eventTypeId, pointerlockChangeEvent, userData)) e.preventDefault();
  7733. };
  7734. var eventHandler = {
  7735. target,
  7736. eventTypeString,
  7737. callbackfunc,
  7738. handlerFunc: pointerlockChangeEventHandlerFunc,
  7739. useCapture
  7740. };
  7741. return JSEvents.registerOrRemoveHandler(eventHandler);
  7742. };
  7743. /** @suppress {missingProperties} */
  7744. var _emscripten_set_pointerlockchange_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) => {
  7745. // TODO: Currently not supported in pthreads or in --proxy-to-worker mode. (In pthreads mode, document object is not defined)
  7746. if (!document || !document.body || (!document.body.requestPointerLock && !document.body.mozRequestPointerLock && !document.body.webkitRequestPointerLock && !document.body.msRequestPointerLock)) {
  7747. return -1;
  7748. }
  7749. target = findEventTarget(target);
  7750. if (!target) return -4;
  7751. registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "mozpointerlockchange", targetThread);
  7752. registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "webkitpointerlockchange", targetThread);
  7753. registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "mspointerlockchange", targetThread);
  7754. return registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "pointerlockchange", targetThread);
  7755. };
  7756. var registerUiEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  7757. JSEvents.uiEvent ||= _malloc(36);
  7758. target = findEventTarget(target);
  7759. var uiEventHandlerFunc = (e = event) => {
  7760. if (e.target != target) {
  7761. // Never take ui events such as scroll via a 'bubbled' route, but always from the direct element that
  7762. // was targeted. Otherwise e.g. if app logs a message in response to a page scroll, the Emscripten log
  7763. // message box could cause to scroll, generating a new (bubbled) scroll message, causing a new log print,
  7764. // causing a new scroll, etc..
  7765. return;
  7766. }
  7767. var b = document.body; // Take document.body to a variable, Closure compiler does not outline access to it on its own.
  7768. if (!b) {
  7769. // During a page unload 'body' can be null, with "Cannot read property 'clientWidth' of null" being thrown
  7770. return;
  7771. }
  7772. var uiEvent = JSEvents.uiEvent;
  7773. HEAP32[((uiEvent)>>2)] = 0; // always zero for resize and scroll
  7774. HEAP32[(((uiEvent)+(4))>>2)] = b.clientWidth;
  7775. HEAP32[(((uiEvent)+(8))>>2)] = b.clientHeight;
  7776. HEAP32[(((uiEvent)+(12))>>2)] = innerWidth;
  7777. HEAP32[(((uiEvent)+(16))>>2)] = innerHeight;
  7778. HEAP32[(((uiEvent)+(20))>>2)] = outerWidth;
  7779. HEAP32[(((uiEvent)+(24))>>2)] = outerHeight;
  7780. HEAP32[(((uiEvent)+(28))>>2)] = pageXOffset | 0; // scroll offsets are float
  7781. HEAP32[(((uiEvent)+(32))>>2)] = pageYOffset | 0;
  7782. if (getWasmTableEntry(callbackfunc)(eventTypeId, uiEvent, userData)) e.preventDefault();
  7783. };
  7784. var eventHandler = {
  7785. target,
  7786. eventTypeString,
  7787. callbackfunc,
  7788. handlerFunc: uiEventHandlerFunc,
  7789. useCapture
  7790. };
  7791. return JSEvents.registerOrRemoveHandler(eventHandler);
  7792. };
  7793. var _emscripten_set_resize_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7794. registerUiEventCallback(target, userData, useCapture, callbackfunc, 10, "resize", targetThread);
  7795. var registerTouchEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  7796. JSEvents.touchEvent ||= _malloc(1552);
  7797. target = findEventTarget(target);
  7798. var touchEventHandlerFunc = (e) => {
  7799. assert(e);
  7800. var t, touches = {}, et = e.touches;
  7801. // To ease marshalling different kinds of touches that browser reports (all touches are listed in e.touches,
  7802. // only changed touches in e.changedTouches, and touches on target at a.targetTouches), mark a boolean in
  7803. // each Touch object so that we can later loop only once over all touches we see to marshall over to Wasm.
  7804. for (let t of et) {
  7805. // Browser might recycle the generated Touch objects between each frame (Firefox on Android), so reset any
  7806. // changed/target states we may have set from previous frame.
  7807. t.isChanged = t.onTarget = 0;
  7808. touches[t.identifier] = t;
  7809. }
  7810. // Mark which touches are part of the changedTouches list.
  7811. for (let t of e.changedTouches) {
  7812. t.isChanged = 1;
  7813. touches[t.identifier] = t;
  7814. }
  7815. // Mark which touches are part of the targetTouches list.
  7816. for (let t of e.targetTouches) {
  7817. touches[t.identifier].onTarget = 1;
  7818. }
  7819. var touchEvent = JSEvents.touchEvent;
  7820. HEAPF64[((touchEvent)>>3)] = e.timeStamp;
  7821. HEAP8[touchEvent + 12] = e.ctrlKey;
  7822. HEAP8[touchEvent + 13] = e.shiftKey;
  7823. HEAP8[touchEvent + 14] = e.altKey;
  7824. HEAP8[touchEvent + 15] = e.metaKey;
  7825. var idx = touchEvent + 16;
  7826. var targetRect = getBoundingClientRect(target);
  7827. var numTouches = 0;
  7828. for (let t of Object.values(touches)) {
  7829. var idx32 = ((idx)>>2); // Pre-shift the ptr to index to HEAP32 to save code size
  7830. HEAP32[idx32 + 0] = t.identifier;
  7831. HEAP32[idx32 + 1] = t.screenX;
  7832. HEAP32[idx32 + 2] = t.screenY;
  7833. HEAP32[idx32 + 3] = t.clientX;
  7834. HEAP32[idx32 + 4] = t.clientY;
  7835. HEAP32[idx32 + 5] = t.pageX;
  7836. HEAP32[idx32 + 6] = t.pageY;
  7837. HEAP8[idx + 28] = t.isChanged;
  7838. HEAP8[idx + 29] = t.onTarget;
  7839. HEAP32[idx32 + 8] = t.clientX - (targetRect.left | 0);
  7840. HEAP32[idx32 + 9] = t.clientY - (targetRect.top | 0);
  7841. idx += 48;
  7842. if (++numTouches > 31) {
  7843. break;
  7844. }
  7845. }
  7846. HEAP32[(((touchEvent)+(8))>>2)] = numTouches;
  7847. if (getWasmTableEntry(callbackfunc)(eventTypeId, touchEvent, userData)) e.preventDefault();
  7848. };
  7849. var eventHandler = {
  7850. target,
  7851. allowsDeferredCalls: eventTypeString == 'touchstart' || eventTypeString == 'touchend',
  7852. eventTypeString,
  7853. callbackfunc,
  7854. handlerFunc: touchEventHandlerFunc,
  7855. useCapture
  7856. };
  7857. return JSEvents.registerOrRemoveHandler(eventHandler);
  7858. };
  7859. var _emscripten_set_touchcancel_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7860. registerTouchEventCallback(target, userData, useCapture, callbackfunc, 25, "touchcancel", targetThread);
  7861. var _emscripten_set_touchend_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7862. registerTouchEventCallback(target, userData, useCapture, callbackfunc, 23, "touchend", targetThread);
  7863. var _emscripten_set_touchmove_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7864. registerTouchEventCallback(target, userData, useCapture, callbackfunc, 24, "touchmove", targetThread);
  7865. var _emscripten_set_touchstart_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  7866. registerTouchEventCallback(target, userData, useCapture, callbackfunc, 22, "touchstart", targetThread);
  7867. var fillVisibilityChangeEventData = (eventStruct) => {
  7868. var visibilityStates = [ "hidden", "visible", "prerender", "unloaded" ];
  7869. var visibilityState = visibilityStates.indexOf(document.visibilityState);
  7870. // Assigning a boolean to HEAP32 with expected type coercion.
  7871. /** @suppress{checkTypes} */
  7872. HEAP8[eventStruct] = document.hidden;
  7873. HEAP32[(((eventStruct)+(4))>>2)] = visibilityState;
  7874. };
  7875. var registerVisibilityChangeEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  7876. JSEvents.visibilityChangeEvent ||= _malloc(8);
  7877. var visibilityChangeEventHandlerFunc = (e = event) => {
  7878. var visibilityChangeEvent = JSEvents.visibilityChangeEvent;
  7879. fillVisibilityChangeEventData(visibilityChangeEvent);
  7880. if (getWasmTableEntry(callbackfunc)(eventTypeId, visibilityChangeEvent, userData)) e.preventDefault();
  7881. };
  7882. var eventHandler = {
  7883. target,
  7884. eventTypeString,
  7885. callbackfunc,
  7886. handlerFunc: visibilityChangeEventHandlerFunc,
  7887. useCapture
  7888. };
  7889. return JSEvents.registerOrRemoveHandler(eventHandler);
  7890. };
  7891. var _emscripten_set_visibilitychange_callback_on_thread = (userData, useCapture, callbackfunc, targetThread) => {
  7892. if (!specialHTMLTargets[1]) {
  7893. return -4;
  7894. }
  7895. return registerVisibilityChangeEventCallback(specialHTMLTargets[1], userData, useCapture, callbackfunc, 21, "visibilitychange", targetThread);
  7896. };
  7897. var registerWheelEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  7898. JSEvents.wheelEvent ||= _malloc(96);
  7899. // The DOM Level 3 events spec event 'wheel'
  7900. var wheelHandlerFunc = (e = event) => {
  7901. var wheelEvent = JSEvents.wheelEvent;
  7902. fillMouseEventData(wheelEvent, e, target);
  7903. HEAPF64[(((wheelEvent)+(64))>>3)] = e["deltaX"];
  7904. HEAPF64[(((wheelEvent)+(72))>>3)] = e["deltaY"];
  7905. HEAPF64[(((wheelEvent)+(80))>>3)] = e["deltaZ"];
  7906. HEAP32[(((wheelEvent)+(88))>>2)] = e["deltaMode"];
  7907. if (getWasmTableEntry(callbackfunc)(eventTypeId, wheelEvent, userData)) e.preventDefault();
  7908. };
  7909. var eventHandler = {
  7910. target,
  7911. allowsDeferredCalls: true,
  7912. eventTypeString,
  7913. callbackfunc,
  7914. handlerFunc: wheelHandlerFunc,
  7915. useCapture
  7916. };
  7917. return JSEvents.registerOrRemoveHandler(eventHandler);
  7918. };
  7919. var _emscripten_set_wheel_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) => {
  7920. target = findEventTarget(target);
  7921. if (!target) return -4;
  7922. if (typeof target.onwheel != 'undefined') {
  7923. return registerWheelEventCallback(target, userData, useCapture, callbackfunc, 9, "wheel", targetThread);
  7924. } else {
  7925. return -1;
  7926. }
  7927. };
  7928. var _emscripten_set_window_title = (title) => document.title = UTF8ToString(title);
  7929. var _emscripten_sleep = () => {
  7930. throw 'Please compile your program with async support in order to use asynchronous operations like emscripten_sleep';
  7931. };
  7932. var ENV = {
  7933. };
  7934. var getExecutableName = () => {
  7935. return thisProgram || './this.program';
  7936. };
  7937. var getEnvStrings = () => {
  7938. if (!getEnvStrings.strings) {
  7939. // Default values.
  7940. // Browser language detection #8751
  7941. var lang = ((typeof navigator == 'object' && navigator.languages && navigator.languages[0]) || 'C').replace('-', '_') + '.UTF-8';
  7942. var env = {
  7943. 'USER': 'web_user',
  7944. 'LOGNAME': 'web_user',
  7945. 'PATH': '/',
  7946. 'PWD': '/',
  7947. 'HOME': '/home/web_user',
  7948. 'LANG': lang,
  7949. '_': getExecutableName()
  7950. };
  7951. // Apply the user-provided values, if any.
  7952. for (var x in ENV) {
  7953. // x is a key in ENV; if ENV[x] is undefined, that means it was
  7954. // explicitly set to be so. We allow user code to do that to
  7955. // force variables with default values to remain unset.
  7956. if (ENV[x] === undefined) delete env[x];
  7957. else env[x] = ENV[x];
  7958. }
  7959. var strings = [];
  7960. for (var x in env) {
  7961. strings.push(`${x}=${env[x]}`);
  7962. }
  7963. getEnvStrings.strings = strings;
  7964. }
  7965. return getEnvStrings.strings;
  7966. };
  7967. var stringToAscii = (str, buffer) => {
  7968. for (var i = 0; i < str.length; ++i) {
  7969. assert(str.charCodeAt(i) === (str.charCodeAt(i) & 0xff));
  7970. HEAP8[buffer++] = str.charCodeAt(i);
  7971. }
  7972. // Null-terminate the string
  7973. HEAP8[buffer] = 0;
  7974. };
  7975. var _environ_get = (__environ, environ_buf) => {
  7976. var bufSize = 0;
  7977. getEnvStrings().forEach((string, i) => {
  7978. var ptr = environ_buf + bufSize;
  7979. HEAPU32[(((__environ)+(i*4))>>2)] = ptr;
  7980. stringToAscii(string, ptr);
  7981. bufSize += string.length + 1;
  7982. });
  7983. return 0;
  7984. };
  7985. var _environ_sizes_get = (penviron_count, penviron_buf_size) => {
  7986. var strings = getEnvStrings();
  7987. HEAPU32[((penviron_count)>>2)] = strings.length;
  7988. var bufSize = 0;
  7989. strings.forEach((string) => bufSize += string.length + 1);
  7990. HEAPU32[((penviron_buf_size)>>2)] = bufSize;
  7991. return 0;
  7992. };
  7993. function _fd_close(fd) {
  7994. try {
  7995. var stream = SYSCALLS.getStreamFromFD(fd);
  7996. FS.close(stream);
  7997. return 0;
  7998. } catch (e) {
  7999. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  8000. return e.errno;
  8001. }
  8002. }
  8003. /** @param {number=} offset */
  8004. var doReadv = (stream, iov, iovcnt, offset) => {
  8005. var ret = 0;
  8006. for (var i = 0; i < iovcnt; i++) {
  8007. var ptr = HEAPU32[((iov)>>2)];
  8008. var len = HEAPU32[(((iov)+(4))>>2)];
  8009. iov += 8;
  8010. var curr = FS.read(stream, HEAP8, ptr, len, offset);
  8011. if (curr < 0) return -1;
  8012. ret += curr;
  8013. if (curr < len) break; // nothing more to read
  8014. if (typeof offset != 'undefined') {
  8015. offset += curr;
  8016. }
  8017. }
  8018. return ret;
  8019. };
  8020. function _fd_read(fd, iov, iovcnt, pnum) {
  8021. try {
  8022. var stream = SYSCALLS.getStreamFromFD(fd);
  8023. var num = doReadv(stream, iov, iovcnt);
  8024. HEAPU32[((pnum)>>2)] = num;
  8025. return 0;
  8026. } catch (e) {
  8027. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  8028. return e.errno;
  8029. }
  8030. }
  8031. function _fd_seek(fd, offset, whence, newOffset) {
  8032. offset = bigintToI53Checked(offset);
  8033. try {
  8034. if (isNaN(offset)) return 61;
  8035. var stream = SYSCALLS.getStreamFromFD(fd);
  8036. FS.llseek(stream, offset, whence);
  8037. HEAP64[((newOffset)>>3)] = BigInt(stream.position);
  8038. if (stream.getdents && offset === 0 && whence === 0) stream.getdents = null; // reset readdir state
  8039. return 0;
  8040. } catch (e) {
  8041. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  8042. return e.errno;
  8043. }
  8044. ;
  8045. }
  8046. /** @param {number=} offset */
  8047. var doWritev = (stream, iov, iovcnt, offset) => {
  8048. var ret = 0;
  8049. for (var i = 0; i < iovcnt; i++) {
  8050. var ptr = HEAPU32[((iov)>>2)];
  8051. var len = HEAPU32[(((iov)+(4))>>2)];
  8052. iov += 8;
  8053. var curr = FS.write(stream, HEAP8, ptr, len, offset);
  8054. if (curr < 0) return -1;
  8055. ret += curr;
  8056. if (curr < len) {
  8057. // No more space to write.
  8058. break;
  8059. }
  8060. if (typeof offset != 'undefined') {
  8061. offset += curr;
  8062. }
  8063. }
  8064. return ret;
  8065. };
  8066. function _fd_write(fd, iov, iovcnt, pnum) {
  8067. try {
  8068. var stream = SYSCALLS.getStreamFromFD(fd);
  8069. var num = doWritev(stream, iov, iovcnt);
  8070. HEAPU32[((pnum)>>2)] = num;
  8071. return 0;
  8072. } catch (e) {
  8073. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  8074. return e.errno;
  8075. }
  8076. }
  8077. var listenOnce = (object, event, func) => {
  8078. object.addEventListener(event, func, { 'once': true });
  8079. };
  8080. /** @param {Object=} elements */
  8081. var autoResumeAudioContext = (ctx, elements) => {
  8082. if (!elements) {
  8083. elements = [document, document.getElementById('canvas')];
  8084. }
  8085. ['keydown', 'mousedown', 'touchstart'].forEach((event) => {
  8086. elements.forEach((element) => {
  8087. if (element) {
  8088. listenOnce(element, event, () => {
  8089. if (ctx.state === 'suspended') ctx.resume();
  8090. });
  8091. }
  8092. });
  8093. });
  8094. };
  8095. var dynCall = (sig, ptr, args = []) => {
  8096. assert(getWasmTableEntry(ptr), `missing table entry in dynCall: ${ptr}`);
  8097. var rtn = getWasmTableEntry(ptr)(...args);
  8098. return rtn;
  8099. };
  8100. var getCFunc = (ident) => {
  8101. var func = Module['_' + ident]; // closure exported function
  8102. assert(func, 'Cannot call unknown function ' + ident + ', make sure it is exported');
  8103. return func;
  8104. };
  8105. var writeArrayToMemory = (array, buffer) => {
  8106. assert(array.length >= 0, 'writeArrayToMemory array must have a length (should be an array or typed array)')
  8107. HEAP8.set(array, buffer);
  8108. };
  8109. /**
  8110. * @param {string|null=} returnType
  8111. * @param {Array=} argTypes
  8112. * @param {Arguments|Array=} args
  8113. * @param {Object=} opts
  8114. */
  8115. var ccall = (ident, returnType, argTypes, args, opts) => {
  8116. // For fast lookup of conversion functions
  8117. var toC = {
  8118. 'string': (str) => {
  8119. var ret = 0;
  8120. if (str !== null && str !== undefined && str !== 0) { // null string
  8121. ret = stringToUTF8OnStack(str);
  8122. }
  8123. return ret;
  8124. },
  8125. 'array': (arr) => {
  8126. var ret = stackAlloc(arr.length);
  8127. writeArrayToMemory(arr, ret);
  8128. return ret;
  8129. }
  8130. };
  8131. function convertReturnValue(ret) {
  8132. if (returnType === 'string') {
  8133. return UTF8ToString(ret);
  8134. }
  8135. if (returnType === 'boolean') return Boolean(ret);
  8136. return ret;
  8137. }
  8138. var func = getCFunc(ident);
  8139. var cArgs = [];
  8140. var stack = 0;
  8141. assert(returnType !== 'array', 'Return type should not be "array".');
  8142. if (args) {
  8143. for (var i = 0; i < args.length; i++) {
  8144. var converter = toC[argTypes[i]];
  8145. if (converter) {
  8146. if (stack === 0) stack = stackSave();
  8147. cArgs[i] = converter(args[i]);
  8148. } else {
  8149. cArgs[i] = args[i];
  8150. }
  8151. }
  8152. }
  8153. var ret = func(...cArgs);
  8154. function onDone(ret) {
  8155. if (stack !== 0) stackRestore(stack);
  8156. return convertReturnValue(ret);
  8157. }
  8158. ret = onDone(ret);
  8159. return ret;
  8160. };
  8161. /**
  8162. * @param {string=} returnType
  8163. * @param {Array=} argTypes
  8164. * @param {Object=} opts
  8165. */
  8166. var cwrap = (ident, returnType, argTypes, opts) => {
  8167. return (...args) => ccall(ident, returnType, argTypes, args, opts);
  8168. };
  8169. FS.createPreloadedFile = FS_createPreloadedFile;
  8170. FS.staticInit();
  8171. // Set module methods based on EXPORTED_RUNTIME_METHODS
  8172. ;
  8173. // exports
  8174. Module["requestFullscreen"] = Browser.requestFullscreen;
  8175. Module["requestFullScreen"] = Browser.requestFullScreen;
  8176. Module["setCanvasSize"] = Browser.setCanvasSize;
  8177. Module["getUserMedia"] = Browser.getUserMedia;
  8178. Module["createContext"] = Browser.createContext;
  8179. ;
  8180. Module["requestAnimationFrame"] = MainLoop.requestAnimationFrame;
  8181. Module["pauseMainLoop"] = MainLoop.pause;
  8182. Module["resumeMainLoop"] = MainLoop.resume;
  8183. MainLoop.init();;
  8184. for (var i = 0; i < 32; ++i) tempFixedLengthArray.push(new Array(i));;
  8185. var miniTempWebGLFloatBuffersStorage = new Float32Array(288);
  8186. // Create GL_POOL_TEMP_BUFFERS_SIZE+1 temporary buffers, for uploads of size 0 through GL_POOL_TEMP_BUFFERS_SIZE inclusive
  8187. for (/**@suppress{duplicate}*/var i = 0; i <= 288; ++i) {
  8188. miniTempWebGLFloatBuffers[i] = miniTempWebGLFloatBuffersStorage.subarray(0, i);
  8189. };
  8190. var miniTempWebGLIntBuffersStorage = new Int32Array(288);
  8191. // Create GL_POOL_TEMP_BUFFERS_SIZE+1 temporary buffers, for uploads of size 0 through GL_POOL_TEMP_BUFFERS_SIZE inclusive
  8192. for (/**@suppress{duplicate}*/var i = 0; i <= 288; ++i) {
  8193. miniTempWebGLIntBuffers[i] = miniTempWebGLIntBuffersStorage.subarray(0, i);
  8194. };
  8195. function checkIncomingModuleAPI() {
  8196. ignoredModuleProp('fetchSettings');
  8197. }
  8198. var wasmImports = {
  8199. /** @export */
  8200. __syscall_fcntl64: ___syscall_fcntl64,
  8201. /** @export */
  8202. __syscall_fstat64: ___syscall_fstat64,
  8203. /** @export */
  8204. __syscall_ioctl: ___syscall_ioctl,
  8205. /** @export */
  8206. __syscall_lstat64: ___syscall_lstat64,
  8207. /** @export */
  8208. __syscall_newfstatat: ___syscall_newfstatat,
  8209. /** @export */
  8210. __syscall_openat: ___syscall_openat,
  8211. /** @export */
  8212. __syscall_stat64: ___syscall_stat64,
  8213. /** @export */
  8214. _abort_js: __abort_js,
  8215. /** @export */
  8216. _emscripten_get_now_is_monotonic: __emscripten_get_now_is_monotonic,
  8217. /** @export */
  8218. _emscripten_throw_longjmp: __emscripten_throw_longjmp,
  8219. /** @export */
  8220. _gmtime_js: __gmtime_js,
  8221. /** @export */
  8222. _tzset_js: __tzset_js,
  8223. /** @export */
  8224. eglBindAPI: _eglBindAPI,
  8225. /** @export */
  8226. eglChooseConfig: _eglChooseConfig,
  8227. /** @export */
  8228. eglCreateContext: _eglCreateContext,
  8229. /** @export */
  8230. eglCreateWindowSurface: _eglCreateWindowSurface,
  8231. /** @export */
  8232. eglDestroyContext: _eglDestroyContext,
  8233. /** @export */
  8234. eglDestroySurface: _eglDestroySurface,
  8235. /** @export */
  8236. eglGetConfigAttrib: _eglGetConfigAttrib,
  8237. /** @export */
  8238. eglGetDisplay: _eglGetDisplay,
  8239. /** @export */
  8240. eglGetError: _eglGetError,
  8241. /** @export */
  8242. eglInitialize: _eglInitialize,
  8243. /** @export */
  8244. eglMakeCurrent: _eglMakeCurrent,
  8245. /** @export */
  8246. eglQueryString: _eglQueryString,
  8247. /** @export */
  8248. eglSwapBuffers: _eglSwapBuffers,
  8249. /** @export */
  8250. eglSwapInterval: _eglSwapInterval,
  8251. /** @export */
  8252. eglTerminate: _eglTerminate,
  8253. /** @export */
  8254. eglWaitGL: _eglWaitGL,
  8255. /** @export */
  8256. eglWaitNative: _eglWaitNative,
  8257. /** @export */
  8258. emscripten_asm_const_int: _emscripten_asm_const_int,
  8259. /** @export */
  8260. emscripten_asm_const_int_sync_on_main_thread: _emscripten_asm_const_int_sync_on_main_thread,
  8261. /** @export */
  8262. emscripten_asm_const_ptr: _emscripten_asm_const_ptr,
  8263. /** @export */
  8264. emscripten_asm_const_ptr_sync_on_main_thread: _emscripten_asm_const_ptr_sync_on_main_thread,
  8265. /** @export */
  8266. emscripten_cancel_main_loop: _emscripten_cancel_main_loop,
  8267. /** @export */
  8268. emscripten_date_now: _emscripten_date_now,
  8269. /** @export */
  8270. emscripten_exit_fullscreen: _emscripten_exit_fullscreen,
  8271. /** @export */
  8272. emscripten_exit_pointerlock: _emscripten_exit_pointerlock,
  8273. /** @export */
  8274. emscripten_force_exit: _emscripten_force_exit,
  8275. /** @export */
  8276. emscripten_get_device_pixel_ratio: _emscripten_get_device_pixel_ratio,
  8277. /** @export */
  8278. emscripten_get_element_css_size: _emscripten_get_element_css_size,
  8279. /** @export */
  8280. emscripten_get_gamepad_status: _emscripten_get_gamepad_status,
  8281. /** @export */
  8282. emscripten_get_now: _emscripten_get_now,
  8283. /** @export */
  8284. emscripten_get_num_gamepads: _emscripten_get_num_gamepads,
  8285. /** @export */
  8286. emscripten_get_screen_size: _emscripten_get_screen_size,
  8287. /** @export */
  8288. emscripten_glActiveTexture: _emscripten_glActiveTexture,
  8289. /** @export */
  8290. emscripten_glAttachShader: _emscripten_glAttachShader,
  8291. /** @export */
  8292. emscripten_glBeginQueryEXT: _emscripten_glBeginQueryEXT,
  8293. /** @export */
  8294. emscripten_glBindAttribLocation: _emscripten_glBindAttribLocation,
  8295. /** @export */
  8296. emscripten_glBindBuffer: _emscripten_glBindBuffer,
  8297. /** @export */
  8298. emscripten_glBindFramebuffer: _emscripten_glBindFramebuffer,
  8299. /** @export */
  8300. emscripten_glBindRenderbuffer: _emscripten_glBindRenderbuffer,
  8301. /** @export */
  8302. emscripten_glBindTexture: _emscripten_glBindTexture,
  8303. /** @export */
  8304. emscripten_glBindVertexArrayOES: _emscripten_glBindVertexArrayOES,
  8305. /** @export */
  8306. emscripten_glBlendColor: _emscripten_glBlendColor,
  8307. /** @export */
  8308. emscripten_glBlendEquation: _emscripten_glBlendEquation,
  8309. /** @export */
  8310. emscripten_glBlendEquationSeparate: _emscripten_glBlendEquationSeparate,
  8311. /** @export */
  8312. emscripten_glBlendFunc: _emscripten_glBlendFunc,
  8313. /** @export */
  8314. emscripten_glBlendFuncSeparate: _emscripten_glBlendFuncSeparate,
  8315. /** @export */
  8316. emscripten_glBufferData: _emscripten_glBufferData,
  8317. /** @export */
  8318. emscripten_glBufferSubData: _emscripten_glBufferSubData,
  8319. /** @export */
  8320. emscripten_glCheckFramebufferStatus: _emscripten_glCheckFramebufferStatus,
  8321. /** @export */
  8322. emscripten_glClear: _emscripten_glClear,
  8323. /** @export */
  8324. emscripten_glClearColor: _emscripten_glClearColor,
  8325. /** @export */
  8326. emscripten_glClearDepthf: _emscripten_glClearDepthf,
  8327. /** @export */
  8328. emscripten_glClearStencil: _emscripten_glClearStencil,
  8329. /** @export */
  8330. emscripten_glClipControlEXT: _emscripten_glClipControlEXT,
  8331. /** @export */
  8332. emscripten_glColorMask: _emscripten_glColorMask,
  8333. /** @export */
  8334. emscripten_glCompileShader: _emscripten_glCompileShader,
  8335. /** @export */
  8336. emscripten_glCompressedTexImage2D: _emscripten_glCompressedTexImage2D,
  8337. /** @export */
  8338. emscripten_glCompressedTexSubImage2D: _emscripten_glCompressedTexSubImage2D,
  8339. /** @export */
  8340. emscripten_glCopyTexImage2D: _emscripten_glCopyTexImage2D,
  8341. /** @export */
  8342. emscripten_glCopyTexSubImage2D: _emscripten_glCopyTexSubImage2D,
  8343. /** @export */
  8344. emscripten_glCreateProgram: _emscripten_glCreateProgram,
  8345. /** @export */
  8346. emscripten_glCreateShader: _emscripten_glCreateShader,
  8347. /** @export */
  8348. emscripten_glCullFace: _emscripten_glCullFace,
  8349. /** @export */
  8350. emscripten_glDeleteBuffers: _emscripten_glDeleteBuffers,
  8351. /** @export */
  8352. emscripten_glDeleteFramebuffers: _emscripten_glDeleteFramebuffers,
  8353. /** @export */
  8354. emscripten_glDeleteProgram: _emscripten_glDeleteProgram,
  8355. /** @export */
  8356. emscripten_glDeleteQueriesEXT: _emscripten_glDeleteQueriesEXT,
  8357. /** @export */
  8358. emscripten_glDeleteRenderbuffers: _emscripten_glDeleteRenderbuffers,
  8359. /** @export */
  8360. emscripten_glDeleteShader: _emscripten_glDeleteShader,
  8361. /** @export */
  8362. emscripten_glDeleteTextures: _emscripten_glDeleteTextures,
  8363. /** @export */
  8364. emscripten_glDeleteVertexArraysOES: _emscripten_glDeleteVertexArraysOES,
  8365. /** @export */
  8366. emscripten_glDepthFunc: _emscripten_glDepthFunc,
  8367. /** @export */
  8368. emscripten_glDepthMask: _emscripten_glDepthMask,
  8369. /** @export */
  8370. emscripten_glDepthRangef: _emscripten_glDepthRangef,
  8371. /** @export */
  8372. emscripten_glDetachShader: _emscripten_glDetachShader,
  8373. /** @export */
  8374. emscripten_glDisable: _emscripten_glDisable,
  8375. /** @export */
  8376. emscripten_glDisableVertexAttribArray: _emscripten_glDisableVertexAttribArray,
  8377. /** @export */
  8378. emscripten_glDrawArrays: _emscripten_glDrawArrays,
  8379. /** @export */
  8380. emscripten_glDrawArraysInstancedANGLE: _emscripten_glDrawArraysInstancedANGLE,
  8381. /** @export */
  8382. emscripten_glDrawBuffersWEBGL: _emscripten_glDrawBuffersWEBGL,
  8383. /** @export */
  8384. emscripten_glDrawElements: _emscripten_glDrawElements,
  8385. /** @export */
  8386. emscripten_glDrawElementsInstancedANGLE: _emscripten_glDrawElementsInstancedANGLE,
  8387. /** @export */
  8388. emscripten_glEnable: _emscripten_glEnable,
  8389. /** @export */
  8390. emscripten_glEnableVertexAttribArray: _emscripten_glEnableVertexAttribArray,
  8391. /** @export */
  8392. emscripten_glEndQueryEXT: _emscripten_glEndQueryEXT,
  8393. /** @export */
  8394. emscripten_glFinish: _emscripten_glFinish,
  8395. /** @export */
  8396. emscripten_glFlush: _emscripten_glFlush,
  8397. /** @export */
  8398. emscripten_glFramebufferRenderbuffer: _emscripten_glFramebufferRenderbuffer,
  8399. /** @export */
  8400. emscripten_glFramebufferTexture2D: _emscripten_glFramebufferTexture2D,
  8401. /** @export */
  8402. emscripten_glFrontFace: _emscripten_glFrontFace,
  8403. /** @export */
  8404. emscripten_glGenBuffers: _emscripten_glGenBuffers,
  8405. /** @export */
  8406. emscripten_glGenFramebuffers: _emscripten_glGenFramebuffers,
  8407. /** @export */
  8408. emscripten_glGenQueriesEXT: _emscripten_glGenQueriesEXT,
  8409. /** @export */
  8410. emscripten_glGenRenderbuffers: _emscripten_glGenRenderbuffers,
  8411. /** @export */
  8412. emscripten_glGenTextures: _emscripten_glGenTextures,
  8413. /** @export */
  8414. emscripten_glGenVertexArraysOES: _emscripten_glGenVertexArraysOES,
  8415. /** @export */
  8416. emscripten_glGenerateMipmap: _emscripten_glGenerateMipmap,
  8417. /** @export */
  8418. emscripten_glGetActiveAttrib: _emscripten_glGetActiveAttrib,
  8419. /** @export */
  8420. emscripten_glGetActiveUniform: _emscripten_glGetActiveUniform,
  8421. /** @export */
  8422. emscripten_glGetAttachedShaders: _emscripten_glGetAttachedShaders,
  8423. /** @export */
  8424. emscripten_glGetAttribLocation: _emscripten_glGetAttribLocation,
  8425. /** @export */
  8426. emscripten_glGetBooleanv: _emscripten_glGetBooleanv,
  8427. /** @export */
  8428. emscripten_glGetBufferParameteriv: _emscripten_glGetBufferParameteriv,
  8429. /** @export */
  8430. emscripten_glGetError: _emscripten_glGetError,
  8431. /** @export */
  8432. emscripten_glGetFloatv: _emscripten_glGetFloatv,
  8433. /** @export */
  8434. emscripten_glGetFramebufferAttachmentParameteriv: _emscripten_glGetFramebufferAttachmentParameteriv,
  8435. /** @export */
  8436. emscripten_glGetIntegerv: _emscripten_glGetIntegerv,
  8437. /** @export */
  8438. emscripten_glGetProgramInfoLog: _emscripten_glGetProgramInfoLog,
  8439. /** @export */
  8440. emscripten_glGetProgramiv: _emscripten_glGetProgramiv,
  8441. /** @export */
  8442. emscripten_glGetQueryObjecti64vEXT: _emscripten_glGetQueryObjecti64vEXT,
  8443. /** @export */
  8444. emscripten_glGetQueryObjectivEXT: _emscripten_glGetQueryObjectivEXT,
  8445. /** @export */
  8446. emscripten_glGetQueryObjectui64vEXT: _emscripten_glGetQueryObjectui64vEXT,
  8447. /** @export */
  8448. emscripten_glGetQueryObjectuivEXT: _emscripten_glGetQueryObjectuivEXT,
  8449. /** @export */
  8450. emscripten_glGetQueryivEXT: _emscripten_glGetQueryivEXT,
  8451. /** @export */
  8452. emscripten_glGetRenderbufferParameteriv: _emscripten_glGetRenderbufferParameteriv,
  8453. /** @export */
  8454. emscripten_glGetShaderInfoLog: _emscripten_glGetShaderInfoLog,
  8455. /** @export */
  8456. emscripten_glGetShaderPrecisionFormat: _emscripten_glGetShaderPrecisionFormat,
  8457. /** @export */
  8458. emscripten_glGetShaderSource: _emscripten_glGetShaderSource,
  8459. /** @export */
  8460. emscripten_glGetShaderiv: _emscripten_glGetShaderiv,
  8461. /** @export */
  8462. emscripten_glGetString: _emscripten_glGetString,
  8463. /** @export */
  8464. emscripten_glGetTexParameterfv: _emscripten_glGetTexParameterfv,
  8465. /** @export */
  8466. emscripten_glGetTexParameteriv: _emscripten_glGetTexParameteriv,
  8467. /** @export */
  8468. emscripten_glGetUniformLocation: _emscripten_glGetUniformLocation,
  8469. /** @export */
  8470. emscripten_glGetUniformfv: _emscripten_glGetUniformfv,
  8471. /** @export */
  8472. emscripten_glGetUniformiv: _emscripten_glGetUniformiv,
  8473. /** @export */
  8474. emscripten_glGetVertexAttribPointerv: _emscripten_glGetVertexAttribPointerv,
  8475. /** @export */
  8476. emscripten_glGetVertexAttribfv: _emscripten_glGetVertexAttribfv,
  8477. /** @export */
  8478. emscripten_glGetVertexAttribiv: _emscripten_glGetVertexAttribiv,
  8479. /** @export */
  8480. emscripten_glHint: _emscripten_glHint,
  8481. /** @export */
  8482. emscripten_glIsBuffer: _emscripten_glIsBuffer,
  8483. /** @export */
  8484. emscripten_glIsEnabled: _emscripten_glIsEnabled,
  8485. /** @export */
  8486. emscripten_glIsFramebuffer: _emscripten_glIsFramebuffer,
  8487. /** @export */
  8488. emscripten_glIsProgram: _emscripten_glIsProgram,
  8489. /** @export */
  8490. emscripten_glIsQueryEXT: _emscripten_glIsQueryEXT,
  8491. /** @export */
  8492. emscripten_glIsRenderbuffer: _emscripten_glIsRenderbuffer,
  8493. /** @export */
  8494. emscripten_glIsShader: _emscripten_glIsShader,
  8495. /** @export */
  8496. emscripten_glIsTexture: _emscripten_glIsTexture,
  8497. /** @export */
  8498. emscripten_glIsVertexArrayOES: _emscripten_glIsVertexArrayOES,
  8499. /** @export */
  8500. emscripten_glLineWidth: _emscripten_glLineWidth,
  8501. /** @export */
  8502. emscripten_glLinkProgram: _emscripten_glLinkProgram,
  8503. /** @export */
  8504. emscripten_glPixelStorei: _emscripten_glPixelStorei,
  8505. /** @export */
  8506. emscripten_glPolygonModeWEBGL: _emscripten_glPolygonModeWEBGL,
  8507. /** @export */
  8508. emscripten_glPolygonOffset: _emscripten_glPolygonOffset,
  8509. /** @export */
  8510. emscripten_glPolygonOffsetClampEXT: _emscripten_glPolygonOffsetClampEXT,
  8511. /** @export */
  8512. emscripten_glQueryCounterEXT: _emscripten_glQueryCounterEXT,
  8513. /** @export */
  8514. emscripten_glReadPixels: _emscripten_glReadPixels,
  8515. /** @export */
  8516. emscripten_glReleaseShaderCompiler: _emscripten_glReleaseShaderCompiler,
  8517. /** @export */
  8518. emscripten_glRenderbufferStorage: _emscripten_glRenderbufferStorage,
  8519. /** @export */
  8520. emscripten_glSampleCoverage: _emscripten_glSampleCoverage,
  8521. /** @export */
  8522. emscripten_glScissor: _emscripten_glScissor,
  8523. /** @export */
  8524. emscripten_glShaderBinary: _emscripten_glShaderBinary,
  8525. /** @export */
  8526. emscripten_glShaderSource: _emscripten_glShaderSource,
  8527. /** @export */
  8528. emscripten_glStencilFunc: _emscripten_glStencilFunc,
  8529. /** @export */
  8530. emscripten_glStencilFuncSeparate: _emscripten_glStencilFuncSeparate,
  8531. /** @export */
  8532. emscripten_glStencilMask: _emscripten_glStencilMask,
  8533. /** @export */
  8534. emscripten_glStencilMaskSeparate: _emscripten_glStencilMaskSeparate,
  8535. /** @export */
  8536. emscripten_glStencilOp: _emscripten_glStencilOp,
  8537. /** @export */
  8538. emscripten_glStencilOpSeparate: _emscripten_glStencilOpSeparate,
  8539. /** @export */
  8540. emscripten_glTexImage2D: _emscripten_glTexImage2D,
  8541. /** @export */
  8542. emscripten_glTexParameterf: _emscripten_glTexParameterf,
  8543. /** @export */
  8544. emscripten_glTexParameterfv: _emscripten_glTexParameterfv,
  8545. /** @export */
  8546. emscripten_glTexParameteri: _emscripten_glTexParameteri,
  8547. /** @export */
  8548. emscripten_glTexParameteriv: _emscripten_glTexParameteriv,
  8549. /** @export */
  8550. emscripten_glTexSubImage2D: _emscripten_glTexSubImage2D,
  8551. /** @export */
  8552. emscripten_glUniform1f: _emscripten_glUniform1f,
  8553. /** @export */
  8554. emscripten_glUniform1fv: _emscripten_glUniform1fv,
  8555. /** @export */
  8556. emscripten_glUniform1i: _emscripten_glUniform1i,
  8557. /** @export */
  8558. emscripten_glUniform1iv: _emscripten_glUniform1iv,
  8559. /** @export */
  8560. emscripten_glUniform2f: _emscripten_glUniform2f,
  8561. /** @export */
  8562. emscripten_glUniform2fv: _emscripten_glUniform2fv,
  8563. /** @export */
  8564. emscripten_glUniform2i: _emscripten_glUniform2i,
  8565. /** @export */
  8566. emscripten_glUniform2iv: _emscripten_glUniform2iv,
  8567. /** @export */
  8568. emscripten_glUniform3f: _emscripten_glUniform3f,
  8569. /** @export */
  8570. emscripten_glUniform3fv: _emscripten_glUniform3fv,
  8571. /** @export */
  8572. emscripten_glUniform3i: _emscripten_glUniform3i,
  8573. /** @export */
  8574. emscripten_glUniform3iv: _emscripten_glUniform3iv,
  8575. /** @export */
  8576. emscripten_glUniform4f: _emscripten_glUniform4f,
  8577. /** @export */
  8578. emscripten_glUniform4fv: _emscripten_glUniform4fv,
  8579. /** @export */
  8580. emscripten_glUniform4i: _emscripten_glUniform4i,
  8581. /** @export */
  8582. emscripten_glUniform4iv: _emscripten_glUniform4iv,
  8583. /** @export */
  8584. emscripten_glUniformMatrix2fv: _emscripten_glUniformMatrix2fv,
  8585. /** @export */
  8586. emscripten_glUniformMatrix3fv: _emscripten_glUniformMatrix3fv,
  8587. /** @export */
  8588. emscripten_glUniformMatrix4fv: _emscripten_glUniformMatrix4fv,
  8589. /** @export */
  8590. emscripten_glUseProgram: _emscripten_glUseProgram,
  8591. /** @export */
  8592. emscripten_glValidateProgram: _emscripten_glValidateProgram,
  8593. /** @export */
  8594. emscripten_glVertexAttrib1f: _emscripten_glVertexAttrib1f,
  8595. /** @export */
  8596. emscripten_glVertexAttrib1fv: _emscripten_glVertexAttrib1fv,
  8597. /** @export */
  8598. emscripten_glVertexAttrib2f: _emscripten_glVertexAttrib2f,
  8599. /** @export */
  8600. emscripten_glVertexAttrib2fv: _emscripten_glVertexAttrib2fv,
  8601. /** @export */
  8602. emscripten_glVertexAttrib3f: _emscripten_glVertexAttrib3f,
  8603. /** @export */
  8604. emscripten_glVertexAttrib3fv: _emscripten_glVertexAttrib3fv,
  8605. /** @export */
  8606. emscripten_glVertexAttrib4f: _emscripten_glVertexAttrib4f,
  8607. /** @export */
  8608. emscripten_glVertexAttrib4fv: _emscripten_glVertexAttrib4fv,
  8609. /** @export */
  8610. emscripten_glVertexAttribDivisorANGLE: _emscripten_glVertexAttribDivisorANGLE,
  8611. /** @export */
  8612. emscripten_glVertexAttribPointer: _emscripten_glVertexAttribPointer,
  8613. /** @export */
  8614. emscripten_glViewport: _emscripten_glViewport,
  8615. /** @export */
  8616. emscripten_has_asyncify: _emscripten_has_asyncify,
  8617. /** @export */
  8618. emscripten_request_fullscreen_strategy: _emscripten_request_fullscreen_strategy,
  8619. /** @export */
  8620. emscripten_request_pointerlock: _emscripten_request_pointerlock,
  8621. /** @export */
  8622. emscripten_resize_heap: _emscripten_resize_heap,
  8623. /** @export */
  8624. emscripten_sample_gamepad_data: _emscripten_sample_gamepad_data,
  8625. /** @export */
  8626. emscripten_set_beforeunload_callback_on_thread: _emscripten_set_beforeunload_callback_on_thread,
  8627. /** @export */
  8628. emscripten_set_blur_callback_on_thread: _emscripten_set_blur_callback_on_thread,
  8629. /** @export */
  8630. emscripten_set_canvas_element_size: _emscripten_set_canvas_element_size,
  8631. /** @export */
  8632. emscripten_set_element_css_size: _emscripten_set_element_css_size,
  8633. /** @export */
  8634. emscripten_set_focus_callback_on_thread: _emscripten_set_focus_callback_on_thread,
  8635. /** @export */
  8636. emscripten_set_fullscreenchange_callback_on_thread: _emscripten_set_fullscreenchange_callback_on_thread,
  8637. /** @export */
  8638. emscripten_set_gamepadconnected_callback_on_thread: _emscripten_set_gamepadconnected_callback_on_thread,
  8639. /** @export */
  8640. emscripten_set_gamepaddisconnected_callback_on_thread: _emscripten_set_gamepaddisconnected_callback_on_thread,
  8641. /** @export */
  8642. emscripten_set_keydown_callback_on_thread: _emscripten_set_keydown_callback_on_thread,
  8643. /** @export */
  8644. emscripten_set_keypress_callback_on_thread: _emscripten_set_keypress_callback_on_thread,
  8645. /** @export */
  8646. emscripten_set_keyup_callback_on_thread: _emscripten_set_keyup_callback_on_thread,
  8647. /** @export */
  8648. emscripten_set_main_loop: _emscripten_set_main_loop,
  8649. /** @export */
  8650. emscripten_set_mousedown_callback_on_thread: _emscripten_set_mousedown_callback_on_thread,
  8651. /** @export */
  8652. emscripten_set_mouseenter_callback_on_thread: _emscripten_set_mouseenter_callback_on_thread,
  8653. /** @export */
  8654. emscripten_set_mouseleave_callback_on_thread: _emscripten_set_mouseleave_callback_on_thread,
  8655. /** @export */
  8656. emscripten_set_mousemove_callback_on_thread: _emscripten_set_mousemove_callback_on_thread,
  8657. /** @export */
  8658. emscripten_set_mouseup_callback_on_thread: _emscripten_set_mouseup_callback_on_thread,
  8659. /** @export */
  8660. emscripten_set_pointerlockchange_callback_on_thread: _emscripten_set_pointerlockchange_callback_on_thread,
  8661. /** @export */
  8662. emscripten_set_resize_callback_on_thread: _emscripten_set_resize_callback_on_thread,
  8663. /** @export */
  8664. emscripten_set_touchcancel_callback_on_thread: _emscripten_set_touchcancel_callback_on_thread,
  8665. /** @export */
  8666. emscripten_set_touchend_callback_on_thread: _emscripten_set_touchend_callback_on_thread,
  8667. /** @export */
  8668. emscripten_set_touchmove_callback_on_thread: _emscripten_set_touchmove_callback_on_thread,
  8669. /** @export */
  8670. emscripten_set_touchstart_callback_on_thread: _emscripten_set_touchstart_callback_on_thread,
  8671. /** @export */
  8672. emscripten_set_visibilitychange_callback_on_thread: _emscripten_set_visibilitychange_callback_on_thread,
  8673. /** @export */
  8674. emscripten_set_wheel_callback_on_thread: _emscripten_set_wheel_callback_on_thread,
  8675. /** @export */
  8676. emscripten_set_window_title: _emscripten_set_window_title,
  8677. /** @export */
  8678. emscripten_sleep: _emscripten_sleep,
  8679. /** @export */
  8680. environ_get: _environ_get,
  8681. /** @export */
  8682. environ_sizes_get: _environ_sizes_get,
  8683. /** @export */
  8684. fd_close: _fd_close,
  8685. /** @export */
  8686. fd_read: _fd_read,
  8687. /** @export */
  8688. fd_seek: _fd_seek,
  8689. /** @export */
  8690. fd_write: _fd_write,
  8691. /** @export */
  8692. invoke_ii,
  8693. /** @export */
  8694. invoke_iii,
  8695. /** @export */
  8696. invoke_iiii,
  8697. /** @export */
  8698. invoke_iiiii,
  8699. /** @export */
  8700. invoke_iiiiii,
  8701. /** @export */
  8702. invoke_v,
  8703. /** @export */
  8704. invoke_vii
  8705. };
  8706. var wasmExports = createWasm();
  8707. var ___wasm_call_ctors = createExportWrapper('__wasm_call_ctors', 0);
  8708. var _main = Module['_main'] = createExportWrapper('__main_argc_argv', 2);
  8709. var _fflush = createExportWrapper('fflush', 1);
  8710. var _free = Module['_free'] = createExportWrapper('free', 1);
  8711. var _malloc = Module['_malloc'] = createExportWrapper('malloc', 1);
  8712. var _meg4_insert = Module['_meg4_insert'] = createExportWrapper('meg4_insert', 3);
  8713. var _strerror = createExportWrapper('strerror', 1);
  8714. var ___funcs_on_exit = createExportWrapper('__funcs_on_exit', 0);
  8715. var _setThrew = createExportWrapper('setThrew', 2);
  8716. var _emscripten_stack_init = () => (_emscripten_stack_init = wasmExports['emscripten_stack_init'])();
  8717. var _emscripten_stack_get_free = () => (_emscripten_stack_get_free = wasmExports['emscripten_stack_get_free'])();
  8718. var _emscripten_stack_get_base = () => (_emscripten_stack_get_base = wasmExports['emscripten_stack_get_base'])();
  8719. var _emscripten_stack_get_end = () => (_emscripten_stack_get_end = wasmExports['emscripten_stack_get_end'])();
  8720. var __emscripten_stack_restore = (a0) => (__emscripten_stack_restore = wasmExports['_emscripten_stack_restore'])(a0);
  8721. var __emscripten_stack_alloc = (a0) => (__emscripten_stack_alloc = wasmExports['_emscripten_stack_alloc'])(a0);
  8722. var _emscripten_stack_get_current = () => (_emscripten_stack_get_current = wasmExports['emscripten_stack_get_current'])();
  8723. function invoke_ii(index,a1) {
  8724. var sp = stackSave();
  8725. try {
  8726. return getWasmTableEntry(index)(a1);
  8727. } catch(e) {
  8728. stackRestore(sp);
  8729. if (e !== e+0) throw e;
  8730. _setThrew(1, 0);
  8731. }
  8732. }
  8733. function invoke_iii(index,a1,a2) {
  8734. var sp = stackSave();
  8735. try {
  8736. return getWasmTableEntry(index)(a1,a2);
  8737. } catch(e) {
  8738. stackRestore(sp);
  8739. if (e !== e+0) throw e;
  8740. _setThrew(1, 0);
  8741. }
  8742. }
  8743. function invoke_iiiiii(index,a1,a2,a3,a4,a5) {
  8744. var sp = stackSave();
  8745. try {
  8746. return getWasmTableEntry(index)(a1,a2,a3,a4,a5);
  8747. } catch(e) {
  8748. stackRestore(sp);
  8749. if (e !== e+0) throw e;
  8750. _setThrew(1, 0);
  8751. }
  8752. }
  8753. function invoke_v(index) {
  8754. var sp = stackSave();
  8755. try {
  8756. getWasmTableEntry(index)();
  8757. } catch(e) {
  8758. stackRestore(sp);
  8759. if (e !== e+0) throw e;
  8760. _setThrew(1, 0);
  8761. }
  8762. }
  8763. function invoke_iiiii(index,a1,a2,a3,a4) {
  8764. var sp = stackSave();
  8765. try {
  8766. return getWasmTableEntry(index)(a1,a2,a3,a4);
  8767. } catch(e) {
  8768. stackRestore(sp);
  8769. if (e !== e+0) throw e;
  8770. _setThrew(1, 0);
  8771. }
  8772. }
  8773. function invoke_iiii(index,a1,a2,a3) {
  8774. var sp = stackSave();
  8775. try {
  8776. return getWasmTableEntry(index)(a1,a2,a3);
  8777. } catch(e) {
  8778. stackRestore(sp);
  8779. if (e !== e+0) throw e;
  8780. _setThrew(1, 0);
  8781. }
  8782. }
  8783. function invoke_vii(index,a1,a2) {
  8784. var sp = stackSave();
  8785. try {
  8786. getWasmTableEntry(index)(a1,a2);
  8787. } catch(e) {
  8788. stackRestore(sp);
  8789. if (e !== e+0) throw e;
  8790. _setThrew(1, 0);
  8791. }
  8792. }
  8793. // include: postamble.js
  8794. // === Auto-generated postamble setup entry stuff ===
  8795. Module['ccall'] = ccall;
  8796. Module['cwrap'] = cwrap;
  8797. var missingLibrarySymbols = [
  8798. 'writeI53ToI64Clamped',
  8799. 'writeI53ToI64Signaling',
  8800. 'writeI53ToU64Clamped',
  8801. 'writeI53ToU64Signaling',
  8802. 'convertI32PairToI53',
  8803. 'convertI32PairToI53Checked',
  8804. 'convertU32PairToI53',
  8805. 'getTempRet0',
  8806. 'setTempRet0',
  8807. 'inetPton4',
  8808. 'inetNtop4',
  8809. 'inetPton6',
  8810. 'inetNtop6',
  8811. 'readSockaddr',
  8812. 'writeSockaddr',
  8813. 'emscriptenLog',
  8814. 'getDynCaller',
  8815. 'asmjsMangle',
  8816. 'HandleAllocator',
  8817. 'getNativeTypeSize',
  8818. 'STACK_SIZE',
  8819. 'STACK_ALIGN',
  8820. 'POINTER_SIZE',
  8821. 'ASSERTIONS',
  8822. 'uleb128Encode',
  8823. 'sigToWasmTypes',
  8824. 'generateFuncType',
  8825. 'convertJsFunctionToWasm',
  8826. 'getEmptyTableSlot',
  8827. 'updateTableMap',
  8828. 'getFunctionAddress',
  8829. 'addFunction',
  8830. 'removeFunction',
  8831. 'reallyNegative',
  8832. 'unSign',
  8833. 'strLen',
  8834. 'reSign',
  8835. 'formatString',
  8836. 'intArrayToString',
  8837. 'AsciiToString',
  8838. 'UTF16ToString',
  8839. 'stringToUTF16',
  8840. 'lengthBytesUTF16',
  8841. 'UTF32ToString',
  8842. 'stringToUTF32',
  8843. 'lengthBytesUTF32',
  8844. 'fillDeviceOrientationEventData',
  8845. 'registerDeviceOrientationEventCallback',
  8846. 'fillDeviceMotionEventData',
  8847. 'registerDeviceMotionEventCallback',
  8848. 'screenOrientation',
  8849. 'fillOrientationChangeEventData',
  8850. 'registerOrientationChangeEventCallback',
  8851. 'hideEverythingExceptGivenElement',
  8852. 'restoreHiddenElements',
  8853. 'softFullscreenResizeWebGLRenderTarget',
  8854. 'registerPointerlockErrorEventCallback',
  8855. 'fillBatteryEventData',
  8856. 'battery',
  8857. 'registerBatteryEventCallback',
  8858. 'jsStackTrace',
  8859. 'getCallstack',
  8860. 'convertPCtoSourceLocation',
  8861. 'checkWasiClock',
  8862. 'wasiRightsToMuslOFlags',
  8863. 'wasiOFlagsToMuslOFlags',
  8864. 'setImmediateWrapped',
  8865. 'safeRequestAnimationFrame',
  8866. 'clearImmediateWrapped',
  8867. 'polyfillSetImmediate',
  8868. 'registerPostMainLoop',
  8869. 'registerPreMainLoop',
  8870. 'getPromise',
  8871. 'makePromise',
  8872. 'idsToPromises',
  8873. 'makePromiseCallback',
  8874. 'ExceptionInfo',
  8875. 'findMatchingCatch',
  8876. 'Browser_asyncPrepareDataCounter',
  8877. 'isLeapYear',
  8878. 'ydayFromDate',
  8879. 'arraySum',
  8880. 'addDays',
  8881. 'getSocketFromFD',
  8882. 'getSocketAddress',
  8883. 'FS_unlink',
  8884. 'FS_mkdirTree',
  8885. '_setNetworkCallback',
  8886. 'writeGLArray',
  8887. 'registerWebGlEventCallback',
  8888. 'runAndAbortIfError',
  8889. 'ALLOC_NORMAL',
  8890. 'ALLOC_STACK',
  8891. 'allocate',
  8892. 'writeStringToMemory',
  8893. 'writeAsciiToMemory',
  8894. 'setErrNo',
  8895. 'demangle',
  8896. 'stackTrace',
  8897. ];
  8898. missingLibrarySymbols.forEach(missingLibrarySymbol)
  8899. var unexportedSymbols = [
  8900. 'run',
  8901. 'addOnPreRun',
  8902. 'addOnInit',
  8903. 'addOnPreMain',
  8904. 'addOnExit',
  8905. 'addOnPostRun',
  8906. 'addRunDependency',
  8907. 'removeRunDependency',
  8908. 'out',
  8909. 'err',
  8910. 'callMain',
  8911. 'abort',
  8912. 'wasmMemory',
  8913. 'wasmExports',
  8914. 'writeStackCookie',
  8915. 'checkStackCookie',
  8916. 'writeI53ToI64',
  8917. 'readI53FromI64',
  8918. 'readI53FromU64',
  8919. 'INT53_MAX',
  8920. 'INT53_MIN',
  8921. 'bigintToI53Checked',
  8922. 'stackSave',
  8923. 'stackRestore',
  8924. 'stackAlloc',
  8925. 'ptrToString',
  8926. 'zeroMemory',
  8927. 'exitJS',
  8928. 'getHeapMax',
  8929. 'growMemory',
  8930. 'ENV',
  8931. 'ERRNO_CODES',
  8932. 'strError',
  8933. 'DNS',
  8934. 'Protocols',
  8935. 'Sockets',
  8936. 'timers',
  8937. 'warnOnce',
  8938. 'readEmAsmArgsArray',
  8939. 'readEmAsmArgs',
  8940. 'runEmAsmFunction',
  8941. 'runMainThreadEmAsm',
  8942. 'jstoi_q',
  8943. 'jstoi_s',
  8944. 'getExecutableName',
  8945. 'listenOnce',
  8946. 'autoResumeAudioContext',
  8947. 'dynCall',
  8948. 'handleException',
  8949. 'keepRuntimeAlive',
  8950. 'runtimeKeepalivePush',
  8951. 'runtimeKeepalivePop',
  8952. 'callUserCallback',
  8953. 'maybeExit',
  8954. 'asyncLoad',
  8955. 'alignMemory',
  8956. 'mmapAlloc',
  8957. 'wasmTable',
  8958. 'noExitRuntime',
  8959. 'getCFunc',
  8960. 'freeTableIndexes',
  8961. 'functionsInTableMap',
  8962. 'setValue',
  8963. 'getValue',
  8964. 'PATH',
  8965. 'PATH_FS',
  8966. 'UTF8Decoder',
  8967. 'UTF8ArrayToString',
  8968. 'UTF8ToString',
  8969. 'stringToUTF8Array',
  8970. 'stringToUTF8',
  8971. 'lengthBytesUTF8',
  8972. 'intArrayFromString',
  8973. 'stringToAscii',
  8974. 'UTF16Decoder',
  8975. 'stringToNewUTF8',
  8976. 'stringToUTF8OnStack',
  8977. 'writeArrayToMemory',
  8978. 'JSEvents',
  8979. 'registerKeyEventCallback',
  8980. 'specialHTMLTargets',
  8981. 'maybeCStringToJsString',
  8982. 'findEventTarget',
  8983. 'findCanvasEventTarget',
  8984. 'getBoundingClientRect',
  8985. 'fillMouseEventData',
  8986. 'registerMouseEventCallback',
  8987. 'registerWheelEventCallback',
  8988. 'registerUiEventCallback',
  8989. 'registerFocusEventCallback',
  8990. 'fillFullscreenChangeEventData',
  8991. 'registerFullscreenChangeEventCallback',
  8992. 'JSEvents_requestFullscreen',
  8993. 'JSEvents_resizeCanvasForFullscreen',
  8994. 'registerRestoreOldStyle',
  8995. 'setLetterbox',
  8996. 'currentFullscreenStrategy',
  8997. 'restoreOldWindowedStyle',
  8998. 'doRequestFullscreen',
  8999. 'fillPointerlockChangeEventData',
  9000. 'registerPointerlockChangeEventCallback',
  9001. 'requestPointerLock',
  9002. 'fillVisibilityChangeEventData',
  9003. 'registerVisibilityChangeEventCallback',
  9004. 'registerTouchEventCallback',
  9005. 'fillGamepadEventData',
  9006. 'registerGamepadEventCallback',
  9007. 'registerBeforeUnloadEventCallback',
  9008. 'setCanvasElementSize',
  9009. 'getCanvasElementSize',
  9010. 'UNWIND_CACHE',
  9011. 'ExitStatus',
  9012. 'getEnvStrings',
  9013. 'doReadv',
  9014. 'doWritev',
  9015. 'initRandomFill',
  9016. 'randomFill',
  9017. 'safeSetTimeout',
  9018. 'promiseMap',
  9019. 'uncaughtExceptionCount',
  9020. 'exceptionLast',
  9021. 'exceptionCaught',
  9022. 'Browser',
  9023. 'getPreloadedImageData__data',
  9024. 'wget',
  9025. 'MONTH_DAYS_REGULAR',
  9026. 'MONTH_DAYS_LEAP',
  9027. 'MONTH_DAYS_REGULAR_CUMULATIVE',
  9028. 'MONTH_DAYS_LEAP_CUMULATIVE',
  9029. 'SYSCALLS',
  9030. 'preloadPlugins',
  9031. 'FS_createPreloadedFile',
  9032. 'FS_modeStringToFlags',
  9033. 'FS_getMode',
  9034. 'FS_stdin_getChar_buffer',
  9035. 'FS_stdin_getChar',
  9036. 'FS_createPath',
  9037. 'FS_createDevice',
  9038. 'FS_readFile',
  9039. 'FS',
  9040. 'FS_createDataFile',
  9041. 'FS_createLazyFile',
  9042. 'MEMFS',
  9043. 'TTY',
  9044. 'PIPEFS',
  9045. 'SOCKFS',
  9046. 'tempFixedLengthArray',
  9047. 'miniTempWebGLFloatBuffers',
  9048. 'miniTempWebGLIntBuffers',
  9049. 'heapObjectForWebGLType',
  9050. 'toTypedArrayIndex',
  9051. 'webgl_enable_ANGLE_instanced_arrays',
  9052. 'webgl_enable_OES_vertex_array_object',
  9053. 'webgl_enable_WEBGL_draw_buffers',
  9054. 'webgl_enable_WEBGL_multi_draw',
  9055. 'webgl_enable_EXT_polygon_offset_clamp',
  9056. 'webgl_enable_EXT_clip_control',
  9057. 'webgl_enable_WEBGL_polygon_mode',
  9058. 'GL',
  9059. 'emscriptenWebGLGet',
  9060. 'computeUnpackAlignedImageSize',
  9061. 'colorChannelsInGlTextureFormat',
  9062. 'emscriptenWebGLGetTexPixelData',
  9063. 'emscriptenWebGLGetUniform',
  9064. 'webglGetUniformLocation',
  9065. 'webglPrepareUniformLocationsBeforeFirstUse',
  9066. 'webglGetLeftBracePos',
  9067. 'emscriptenWebGLGetVertexAttrib',
  9068. '__glGetActiveAttribOrUniform',
  9069. 'AL',
  9070. 'GLUT',
  9071. 'EGL',
  9072. 'GLEW',
  9073. 'IDBStore',
  9074. 'allocateUTF8',
  9075. 'allocateUTF8OnStack',
  9076. 'print',
  9077. 'printErr',
  9078. ];
  9079. unexportedSymbols.forEach(unexportedRuntimeSymbol);
  9080. var calledRun;
  9081. dependenciesFulfilled = function runCaller() {
  9082. // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
  9083. if (!calledRun) run();
  9084. if (!calledRun) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
  9085. };
  9086. function callMain(args = []) {
  9087. assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on Module["onRuntimeInitialized"])');
  9088. assert(__ATPRERUN__.length == 0, 'cannot call main when preRun functions remain to be called');
  9089. var entryFunction = _main;
  9090. args.unshift(thisProgram);
  9091. var argc = args.length;
  9092. var argv = stackAlloc((argc + 1) * 4);
  9093. var argv_ptr = argv;
  9094. args.forEach((arg) => {
  9095. HEAPU32[((argv_ptr)>>2)] = stringToUTF8OnStack(arg);
  9096. argv_ptr += 4;
  9097. });
  9098. HEAPU32[((argv_ptr)>>2)] = 0;
  9099. try {
  9100. var ret = entryFunction(argc, argv);
  9101. // if we're not running an evented main loop, it's time to exit
  9102. exitJS(ret, /* implicit = */ true);
  9103. return ret;
  9104. }
  9105. catch (e) {
  9106. return handleException(e);
  9107. }
  9108. }
  9109. function stackCheckInit() {
  9110. // This is normally called automatically during __wasm_call_ctors but need to
  9111. // get these values before even running any of the ctors so we call it redundantly
  9112. // here.
  9113. _emscripten_stack_init();
  9114. // TODO(sbc): Move writeStackCookie to native to to avoid this.
  9115. writeStackCookie();
  9116. }
  9117. function run(args = arguments_) {
  9118. if (runDependencies > 0) {
  9119. return;
  9120. }
  9121. stackCheckInit();
  9122. preRun();
  9123. // a preRun added a dependency, run will be called later
  9124. if (runDependencies > 0) {
  9125. return;
  9126. }
  9127. function doRun() {
  9128. // run may have just been called through dependencies being fulfilled just in this very frame,
  9129. // or while the async setStatus time below was happening
  9130. if (calledRun) return;
  9131. calledRun = true;
  9132. Module['calledRun'] = true;
  9133. if (ABORT) return;
  9134. initRuntime();
  9135. preMain();
  9136. Module['onRuntimeInitialized']?.();
  9137. if (shouldRunNow) callMain(args);
  9138. postRun();
  9139. }
  9140. if (Module['setStatus']) {
  9141. Module['setStatus']('Running...');
  9142. setTimeout(() => {
  9143. setTimeout(() => Module['setStatus'](''), 1);
  9144. doRun();
  9145. }, 1);
  9146. } else
  9147. {
  9148. doRun();
  9149. }
  9150. checkStackCookie();
  9151. }
  9152. if (Module['preInit']) {
  9153. if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];
  9154. while (Module['preInit'].length > 0) {
  9155. Module['preInit'].pop()();
  9156. }
  9157. }
  9158. // shouldRunNow refers to calling main(), not run().
  9159. var shouldRunNow = true;
  9160. if (Module['noInitialRun']) shouldRunNow = false;
  9161. run();
  9162. // end include: postamble.js