index.js 367 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193
  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. }
  27. // --pre-jses are emitted after the Module integration code, so that they can
  28. // refer to Module (if they choose; they can also define Module)
  29. // Sometimes an existing Module object exists with properties
  30. // meant to overwrite the default module functionality. Here
  31. // we collect those properties and reapply _after_ we configure
  32. // the current environment's defaults to avoid having to be so
  33. // defensive during initialization.
  34. var moduleOverrides = Object.assign({}, Module);
  35. var arguments_ = [];
  36. var thisProgram = './this.program';
  37. var quit_ = (status, toThrow) => {
  38. throw toThrow;
  39. };
  40. // `/` should be present at the end if `scriptDirectory` is not empty
  41. var scriptDirectory = '';
  42. function locateFile(path) {
  43. if (Module['locateFile']) {
  44. return Module['locateFile'](path, scriptDirectory);
  45. }
  46. return scriptDirectory + path;
  47. }
  48. // Hooks that are implemented differently in different runtime environments.
  49. var readAsync, readBinary;
  50. if (ENVIRONMENT_IS_NODE) {
  51. 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?)');
  52. var nodeVersion = process.versions.node;
  53. var numericVersion = nodeVersion.split('.').slice(0, 3);
  54. numericVersion = (numericVersion[0] * 10000) + (numericVersion[1] * 100) + (numericVersion[2].split('-')[0] * 1);
  55. var minVersion = 160000;
  56. if (numericVersion < 160000) {
  57. throw new Error('This emscripten-generated code requires node v16.0.0 (detected v' + nodeVersion + ')');
  58. }
  59. // These modules will usually be used on Node.js. Load them eagerly to avoid
  60. // the complexity of lazy-loading.
  61. var fs = require('fs');
  62. var nodePath = require('path');
  63. scriptDirectory = __dirname + '/';
  64. // include: node_shell_read.js
  65. readBinary = (filename) => {
  66. // We need to re-wrap `file://` strings to URLs.
  67. filename = isFileURI(filename) ? new URL(filename) : filename;
  68. var ret = fs.readFileSync(filename);
  69. assert(Buffer.isBuffer(ret));
  70. return ret;
  71. };
  72. readAsync = async (filename, binary = true) => {
  73. // See the comment in the `readBinary` function.
  74. filename = isFileURI(filename) ? new URL(filename) : filename;
  75. var ret = fs.readFileSync(filename, binary ? undefined : 'utf8');
  76. assert(binary ? Buffer.isBuffer(ret) : typeof ret == 'string');
  77. return ret;
  78. };
  79. // end include: node_shell_read.js
  80. if (!Module['thisProgram'] && process.argv.length > 1) {
  81. thisProgram = process.argv[1].replace(/\\/g, '/');
  82. }
  83. arguments_ = process.argv.slice(2);
  84. if (typeof module != 'undefined') {
  85. module['exports'] = Module;
  86. }
  87. quit_ = (status, toThrow) => {
  88. process.exitCode = status;
  89. throw toThrow;
  90. };
  91. } else
  92. if (ENVIRONMENT_IS_SHELL) {
  93. 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?)');
  94. } else
  95. // Note that this includes Node.js workers when relevant (pthreads is enabled).
  96. // Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and
  97. // ENVIRONMENT_IS_NODE.
  98. if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
  99. if (ENVIRONMENT_IS_WORKER) { // Check worker, not web, since window could be polyfilled
  100. scriptDirectory = self.location.href;
  101. } else if (typeof document != 'undefined' && document.currentScript) { // web
  102. scriptDirectory = document.currentScript.src;
  103. }
  104. // blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them.
  105. // otherwise, slice off the final part of the url to find the script directory.
  106. // if scriptDirectory does not contain a slash, lastIndexOf will return -1,
  107. // and scriptDirectory will correctly be replaced with an empty string.
  108. // If scriptDirectory contains a query (starting with ?) or a fragment (starting with #),
  109. // they are removed because they could contain a slash.
  110. if (scriptDirectory.startsWith('blob:')) {
  111. scriptDirectory = '';
  112. } else {
  113. scriptDirectory = scriptDirectory.slice(0, scriptDirectory.replace(/[?#].*/, '').lastIndexOf('/')+1);
  114. }
  115. 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?)');
  116. {
  117. // include: web_or_worker_shell_read.js
  118. if (ENVIRONMENT_IS_WORKER) {
  119. readBinary = (url) => {
  120. var xhr = new XMLHttpRequest();
  121. xhr.open('GET', url, false);
  122. xhr.responseType = 'arraybuffer';
  123. xhr.send(null);
  124. return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response));
  125. };
  126. }
  127. readAsync = async (url) => {
  128. // Fetch has some additional restrictions over XHR, like it can't be used on a file:// url.
  129. // See https://github.com/github/fetch/pull/92#issuecomment-140665932
  130. // Cordova or Electron apps are typically loaded from a file:// url.
  131. // So use XHR on webview if URL is a file URL.
  132. if (isFileURI(url)) {
  133. return new Promise((resolve, reject) => {
  134. var xhr = new XMLHttpRequest();
  135. xhr.open('GET', url, true);
  136. xhr.responseType = 'arraybuffer';
  137. xhr.onload = () => {
  138. if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
  139. resolve(xhr.response);
  140. return;
  141. }
  142. reject(xhr.status);
  143. };
  144. xhr.onerror = reject;
  145. xhr.send(null);
  146. });
  147. }
  148. var response = await fetch(url, { credentials: 'same-origin' });
  149. if (response.ok) {
  150. return response.arrayBuffer();
  151. }
  152. throw new Error(response.status + ' : ' + response.url);
  153. };
  154. // end include: web_or_worker_shell_read.js
  155. }
  156. } else
  157. {
  158. throw new Error('environment detection error');
  159. }
  160. var out = Module['print'] || console.log.bind(console);
  161. var err = Module['printErr'] || console.error.bind(console);
  162. // Merge back in the overrides
  163. Object.assign(Module, moduleOverrides);
  164. // Free the object hierarchy contained in the overrides, this lets the GC
  165. // reclaim data used.
  166. moduleOverrides = null;
  167. checkIncomingModuleAPI();
  168. // Emit code to handle expected values on the Module object. This applies Module.x
  169. // to the proper local x. This has two benefits: first, we only emit it if it is
  170. // expected to arrive, and second, by using a local everywhere else that can be
  171. // minified.
  172. if (Module['arguments']) arguments_ = Module['arguments'];legacyModuleProp('arguments', 'arguments_');
  173. if (Module['thisProgram']) thisProgram = Module['thisProgram'];legacyModuleProp('thisProgram', 'thisProgram');
  174. // perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message
  175. // Assertions on removed incoming Module JS APIs.
  176. assert(typeof Module['memoryInitializerPrefixURL'] == 'undefined', 'Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead');
  177. assert(typeof Module['pthreadMainPrefixURL'] == 'undefined', 'Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead');
  178. assert(typeof Module['cdInitializerPrefixURL'] == 'undefined', 'Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead');
  179. assert(typeof Module['filePackagePrefixURL'] == 'undefined', 'Module.filePackagePrefixURL option was removed, use Module.locateFile instead');
  180. assert(typeof Module['read'] == 'undefined', 'Module.read option was removed');
  181. assert(typeof Module['readAsync'] == 'undefined', 'Module.readAsync option was removed (modify readAsync in JS)');
  182. assert(typeof Module['readBinary'] == 'undefined', 'Module.readBinary option was removed (modify readBinary in JS)');
  183. assert(typeof Module['setWindowTitle'] == 'undefined', 'Module.setWindowTitle option was removed (modify emscripten_set_window_title in JS)');
  184. assert(typeof Module['TOTAL_MEMORY'] == 'undefined', 'Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY');
  185. legacyModuleProp('asm', 'wasmExports');
  186. legacyModuleProp('readAsync', 'readAsync');
  187. legacyModuleProp('readBinary', 'readBinary');
  188. legacyModuleProp('setWindowTitle', 'setWindowTitle');
  189. var IDBFS = 'IDBFS is no longer included by default; build with -lidbfs.js';
  190. var PROXYFS = 'PROXYFS is no longer included by default; build with -lproxyfs.js';
  191. var WORKERFS = 'WORKERFS is no longer included by default; build with -lworkerfs.js';
  192. var FETCHFS = 'FETCHFS is no longer included by default; build with -lfetchfs.js';
  193. var ICASEFS = 'ICASEFS is no longer included by default; build with -licasefs.js';
  194. var JSFILEFS = 'JSFILEFS is no longer included by default; build with -ljsfilefs.js';
  195. var OPFS = 'OPFS is no longer included by default; build with -lopfs.js';
  196. var NODEFS = 'NODEFS is no longer included by default; build with -lnodefs.js';
  197. assert(!ENVIRONMENT_IS_SHELL, 'shell environment detected but not enabled at build time. Add `shell` to `-sENVIRONMENT` to enable.');
  198. // end include: shell.js
  199. // include: preamble.js
  200. // === Preamble library stuff ===
  201. // Documentation for the public APIs defined in this file must be updated in:
  202. // site/source/docs/api_reference/preamble.js.rst
  203. // A prebuilt local version of the documentation is available at:
  204. // site/build/text/docs/api_reference/preamble.js.txt
  205. // You can also build docs locally as HTML or other formats in site/
  206. // An online HTML version (which may be of a different version of Emscripten)
  207. // is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html
  208. var wasmBinary = Module['wasmBinary'];legacyModuleProp('wasmBinary', 'wasmBinary');
  209. if (typeof WebAssembly != 'object') {
  210. err('no native wasm support detected');
  211. }
  212. // Wasm globals
  213. var wasmMemory;
  214. //========================================
  215. // Runtime essentials
  216. //========================================
  217. // whether we are quitting the application. no code should run after this.
  218. // set in exit() and abort()
  219. var ABORT = false;
  220. // set by exit() and abort(). Passed to 'onExit' handler.
  221. // NOTE: This is also used as the process return code code in shell environments
  222. // but only when noExitRuntime is false.
  223. var EXITSTATUS;
  224. // In STRICT mode, we only define assert() when ASSERTIONS is set. i.e. we
  225. // don't define it at all in release modes. This matches the behaviour of
  226. // MINIMAL_RUNTIME.
  227. // TODO(sbc): Make this the default even without STRICT enabled.
  228. /** @type {function(*, string=)} */
  229. function assert(condition, text) {
  230. if (!condition) {
  231. abort('Assertion failed' + (text ? ': ' + text : ''));
  232. }
  233. }
  234. // We used to include malloc/free by default in the past. Show a helpful error in
  235. // builds with assertions.
  236. // Memory management
  237. var HEAP,
  238. /** @type {!Int8Array} */
  239. HEAP8,
  240. /** @type {!Uint8Array} */
  241. HEAPU8,
  242. /** @type {!Int16Array} */
  243. HEAP16,
  244. /** @type {!Uint16Array} */
  245. HEAPU16,
  246. /** @type {!Int32Array} */
  247. HEAP32,
  248. /** @type {!Uint32Array} */
  249. HEAPU32,
  250. /** @type {!Float32Array} */
  251. HEAPF32,
  252. /* BigInt64Array type is not correctly defined in closure
  253. /** not-@type {!BigInt64Array} */
  254. HEAP64,
  255. /* BigUint64Array type is not correctly defined in closure
  256. /** not-t@type {!BigUint64Array} */
  257. HEAPU64,
  258. /** @type {!Float64Array} */
  259. HEAPF64;
  260. var runtimeInitialized = false;
  261. /**
  262. * Indicates whether filename is delivered via file protocol (as opposed to http/https)
  263. * @noinline
  264. */
  265. var isFileURI = (filename) => filename.startsWith('file://');
  266. // include: runtime_shared.js
  267. // include: runtime_stack_check.js
  268. // Initializes the stack cookie. Called at the startup of main and at the startup of each thread in pthreads mode.
  269. function writeStackCookie() {
  270. var max = _emscripten_stack_get_end();
  271. assert((max & 3) == 0);
  272. // If the stack ends at address zero we write our cookies 4 bytes into the
  273. // stack. This prevents interference with SAFE_HEAP and ASAN which also
  274. // monitor writes to address zero.
  275. if (max == 0) {
  276. max += 4;
  277. }
  278. // The stack grow downwards towards _emscripten_stack_get_end.
  279. // We write cookies to the final two words in the stack and detect if they are
  280. // ever overwritten.
  281. HEAPU32[((max)>>2)] = 0x02135467;
  282. HEAPU32[(((max)+(4))>>2)] = 0x89BACDFE;
  283. // Also test the global address 0 for integrity.
  284. HEAPU32[((0)>>2)] = 1668509029;
  285. }
  286. function checkStackCookie() {
  287. if (ABORT) return;
  288. var max = _emscripten_stack_get_end();
  289. // See writeStackCookie().
  290. if (max == 0) {
  291. max += 4;
  292. }
  293. var cookie1 = HEAPU32[((max)>>2)];
  294. var cookie2 = HEAPU32[(((max)+(4))>>2)];
  295. if (cookie1 != 0x02135467 || cookie2 != 0x89BACDFE) {
  296. abort(`Stack overflow! Stack cookie has been overwritten at ${ptrToString(max)}, expected hex dwords 0x89BACDFE and 0x2135467, but received ${ptrToString(cookie2)} ${ptrToString(cookie1)}`);
  297. }
  298. // Also test the global address 0 for integrity.
  299. if (HEAPU32[((0)>>2)] != 0x63736d65 /* 'emsc' */) {
  300. abort('Runtime error: The application has corrupted its heap memory area (address zero)!');
  301. }
  302. }
  303. // end include: runtime_stack_check.js
  304. // include: runtime_exceptions.js
  305. // end include: runtime_exceptions.js
  306. // include: runtime_debug.js
  307. // Endianness check
  308. (() => {
  309. var h16 = new Int16Array(1);
  310. var h8 = new Int8Array(h16.buffer);
  311. h16[0] = 0x6373;
  312. if (h8[0] !== 0x73 || h8[1] !== 0x63) throw 'Runtime error: expected the system to be little-endian! (Run with -sSUPPORT_BIG_ENDIAN to bypass)';
  313. })();
  314. if (Module['ENVIRONMENT']) {
  315. 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)');
  316. }
  317. function legacyModuleProp(prop, newName, incoming=true) {
  318. if (!Object.getOwnPropertyDescriptor(Module, prop)) {
  319. Object.defineProperty(Module, prop, {
  320. configurable: true,
  321. get() {
  322. 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)' : '';
  323. abort(`\`Module.${prop}\` has been replaced by \`${newName}\`` + extra);
  324. }
  325. });
  326. }
  327. }
  328. function ignoredModuleProp(prop) {
  329. if (Object.getOwnPropertyDescriptor(Module, prop)) {
  330. abort(`\`Module.${prop}\` was supplied but \`${prop}\` not included in INCOMING_MODULE_JS_API`);
  331. }
  332. }
  333. // forcing the filesystem exports a few things by default
  334. function isExportedByForceFilesystem(name) {
  335. return name === 'FS_createPath' ||
  336. name === 'FS_createDataFile' ||
  337. name === 'FS_createPreloadedFile' ||
  338. name === 'FS_unlink' ||
  339. name === 'addRunDependency' ||
  340. // The old FS has some functionality that WasmFS lacks.
  341. name === 'FS_createLazyFile' ||
  342. name === 'FS_createDevice' ||
  343. name === 'removeRunDependency';
  344. }
  345. /**
  346. * Intercept access to a global symbol. This enables us to give informative
  347. * warnings/errors when folks attempt to use symbols they did not include in
  348. * their build, or no symbols that no longer exist.
  349. */
  350. function hookGlobalSymbolAccess(sym, func) {
  351. if (typeof globalThis != 'undefined' && !Object.getOwnPropertyDescriptor(globalThis, sym)) {
  352. Object.defineProperty(globalThis, sym, {
  353. configurable: true,
  354. get() {
  355. func();
  356. return undefined;
  357. }
  358. });
  359. }
  360. }
  361. function missingGlobal(sym, msg) {
  362. hookGlobalSymbolAccess(sym, () => {
  363. warnOnce(`\`${sym}\` is not longer defined by emscripten. ${msg}`);
  364. });
  365. }
  366. missingGlobal('buffer', 'Please use HEAP8.buffer or wasmMemory.buffer');
  367. missingGlobal('asm', 'Please use wasmExports instead');
  368. function missingLibrarySymbol(sym) {
  369. hookGlobalSymbolAccess(sym, () => {
  370. // Can't `abort()` here because it would break code that does runtime
  371. // checks. e.g. `if (typeof SDL === 'undefined')`.
  372. 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`;
  373. // DEFAULT_LIBRARY_FUNCS_TO_INCLUDE requires the name as it appears in
  374. // library.js, which means $name for a JS name with no prefix, or name
  375. // for a JS name like _name.
  376. var librarySymbol = sym;
  377. if (!librarySymbol.startsWith('_')) {
  378. librarySymbol = '$' + sym;
  379. }
  380. msg += ` (e.g. -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE='${librarySymbol}')`;
  381. if (isExportedByForceFilesystem(sym)) {
  382. msg += '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you';
  383. }
  384. warnOnce(msg);
  385. });
  386. // Any symbol that is not included from the JS library is also (by definition)
  387. // not exported on the Module object.
  388. unexportedRuntimeSymbol(sym);
  389. }
  390. function unexportedRuntimeSymbol(sym) {
  391. if (!Object.getOwnPropertyDescriptor(Module, sym)) {
  392. Object.defineProperty(Module, sym, {
  393. configurable: true,
  394. get() {
  395. var msg = `'${sym}' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the Emscripten FAQ)`;
  396. if (isExportedByForceFilesystem(sym)) {
  397. msg += '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you';
  398. }
  399. abort(msg);
  400. }
  401. });
  402. }
  403. }
  404. // Used by XXXXX_DEBUG settings to output debug messages.
  405. function dbg(...args) {
  406. // TODO(sbc): Make this configurable somehow. Its not always convenient for
  407. // logging to show up as warnings.
  408. console.warn(...args);
  409. }
  410. // end include: runtime_debug.js
  411. // include: memoryprofiler.js
  412. // end include: memoryprofiler.js
  413. function updateMemoryViews() {
  414. var b = wasmMemory.buffer;
  415. Module['HEAP8'] = HEAP8 = new Int8Array(b);
  416. Module['HEAP16'] = HEAP16 = new Int16Array(b);
  417. Module['HEAPU8'] = HEAPU8 = new Uint8Array(b);
  418. Module['HEAPU16'] = HEAPU16 = new Uint16Array(b);
  419. Module['HEAP32'] = HEAP32 = new Int32Array(b);
  420. Module['HEAPU32'] = HEAPU32 = new Uint32Array(b);
  421. Module['HEAPF32'] = HEAPF32 = new Float32Array(b);
  422. Module['HEAPF64'] = HEAPF64 = new Float64Array(b);
  423. Module['HEAP64'] = HEAP64 = new BigInt64Array(b);
  424. Module['HEAPU64'] = HEAPU64 = new BigUint64Array(b);
  425. }
  426. // end include: runtime_shared.js
  427. assert(!Module['STACK_SIZE'], 'STACK_SIZE can no longer be set at runtime. Use -sSTACK_SIZE at link time')
  428. assert(typeof Int32Array != 'undefined' && typeof Float64Array !== 'undefined' && Int32Array.prototype.subarray != undefined && Int32Array.prototype.set != undefined,
  429. 'JS engine does not provide full typed array support');
  430. // If memory is defined in wasm, the user can't provide it, or set INITIAL_MEMORY
  431. assert(!Module['wasmMemory'], 'Use of `wasmMemory` detected. Use -sIMPORTED_MEMORY to define wasmMemory externally');
  432. assert(!Module['INITIAL_MEMORY'], 'Detected runtime INITIAL_MEMORY setting. Use -sIMPORTED_MEMORY to define wasmMemory dynamically');
  433. function preRun() {
  434. if (Module['preRun']) {
  435. if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];
  436. while (Module['preRun'].length) {
  437. addOnPreRun(Module['preRun'].shift());
  438. }
  439. }
  440. callRuntimeCallbacks(onPreRuns);
  441. }
  442. function initRuntime() {
  443. assert(!runtimeInitialized);
  444. runtimeInitialized = true;
  445. checkStackCookie();
  446. if (!Module['noFSInit'] && !FS.initialized) FS.init();
  447. TTY.init();
  448. wasmExports['__wasm_call_ctors']();
  449. FS.ignorePermissions = false;
  450. }
  451. function preMain() {
  452. checkStackCookie();
  453. }
  454. function postRun() {
  455. checkStackCookie();
  456. if (Module['postRun']) {
  457. if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];
  458. while (Module['postRun'].length) {
  459. addOnPostRun(Module['postRun'].shift());
  460. }
  461. }
  462. callRuntimeCallbacks(onPostRuns);
  463. }
  464. // A counter of dependencies for calling run(). If we need to
  465. // do asynchronous work before running, increment this and
  466. // decrement it. Incrementing must happen in a place like
  467. // Module.preRun (used by emcc to add file preloading).
  468. // Note that you can add dependencies in preRun, even though
  469. // it happens right before run - run will be postponed until
  470. // the dependencies are met.
  471. var runDependencies = 0;
  472. var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled
  473. var runDependencyTracking = {};
  474. var runDependencyWatcher = null;
  475. function getUniqueRunDependency(id) {
  476. var orig = id;
  477. while (1) {
  478. if (!runDependencyTracking[id]) return id;
  479. id = orig + Math.random();
  480. }
  481. }
  482. function addRunDependency(id) {
  483. runDependencies++;
  484. Module['monitorRunDependencies']?.(runDependencies);
  485. if (id) {
  486. assert(!runDependencyTracking[id]);
  487. runDependencyTracking[id] = 1;
  488. if (runDependencyWatcher === null && typeof setInterval != 'undefined') {
  489. // Check for missing dependencies every few seconds
  490. runDependencyWatcher = setInterval(() => {
  491. if (ABORT) {
  492. clearInterval(runDependencyWatcher);
  493. runDependencyWatcher = null;
  494. return;
  495. }
  496. var shown = false;
  497. for (var dep in runDependencyTracking) {
  498. if (!shown) {
  499. shown = true;
  500. err('still waiting on run dependencies:');
  501. }
  502. err(`dependency: ${dep}`);
  503. }
  504. if (shown) {
  505. err('(end of list)');
  506. }
  507. }, 10000);
  508. }
  509. } else {
  510. err('warning: run dependency added without ID');
  511. }
  512. }
  513. function removeRunDependency(id) {
  514. runDependencies--;
  515. Module['monitorRunDependencies']?.(runDependencies);
  516. if (id) {
  517. assert(runDependencyTracking[id]);
  518. delete runDependencyTracking[id];
  519. } else {
  520. err('warning: run dependency removed without ID');
  521. }
  522. if (runDependencies == 0) {
  523. if (runDependencyWatcher !== null) {
  524. clearInterval(runDependencyWatcher);
  525. runDependencyWatcher = null;
  526. }
  527. if (dependenciesFulfilled) {
  528. var callback = dependenciesFulfilled;
  529. dependenciesFulfilled = null;
  530. callback(); // can add another dependenciesFulfilled
  531. }
  532. }
  533. }
  534. /** @param {string|number=} what */
  535. function abort(what) {
  536. Module['onAbort']?.(what);
  537. what = 'Aborted(' + what + ')';
  538. // TODO(sbc): Should we remove printing and leave it up to whoever
  539. // catches the exception?
  540. err(what);
  541. ABORT = true;
  542. // Use a wasm runtime error, because a JS error might be seen as a foreign
  543. // exception, which means we'd run destructors on it. We need the error to
  544. // simply make the program stop.
  545. // FIXME This approach does not work in Wasm EH because it currently does not assume
  546. // all RuntimeErrors are from traps; it decides whether a RuntimeError is from
  547. // a trap or not based on a hidden field within the object. So at the moment
  548. // we don't have a way of throwing a wasm trap from JS. TODO Make a JS API that
  549. // allows this in the wasm spec.
  550. // Suppress closure compiler warning here. Closure compiler's builtin extern
  551. // definition for WebAssembly.RuntimeError claims it takes no arguments even
  552. // though it can.
  553. // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure gets fixed.
  554. /** @suppress {checkTypes} */
  555. var e = new WebAssembly.RuntimeError(what);
  556. // Throw the error whether or not MODULARIZE is set because abort is used
  557. // in code paths apart from instantiation where an exception is expected
  558. // to be thrown when abort is called.
  559. throw e;
  560. }
  561. function createExportWrapper(name, nargs) {
  562. return (...args) => {
  563. assert(runtimeInitialized, `native function \`${name}\` called before runtime initialization`);
  564. var f = wasmExports[name];
  565. assert(f, `exported native function \`${name}\` not found`);
  566. // Only assert for too many arguments. Too few can be valid since the missing arguments will be zero filled.
  567. assert(args.length <= nargs, `native function \`${name}\` called with ${args.length} args but expects ${nargs}`);
  568. return f(...args);
  569. };
  570. }
  571. var wasmBinaryFile;
  572. function findWasmBinary() {
  573. return locateFile('index.wasm');
  574. }
  575. function getBinarySync(file) {
  576. if (file == wasmBinaryFile && wasmBinary) {
  577. return new Uint8Array(wasmBinary);
  578. }
  579. if (readBinary) {
  580. return readBinary(file);
  581. }
  582. throw 'both async and sync fetching of the wasm failed';
  583. }
  584. async function getWasmBinary(binaryFile) {
  585. // If we don't have the binary yet, load it asynchronously using readAsync.
  586. if (!wasmBinary) {
  587. // Fetch the binary using readAsync
  588. try {
  589. var response = await readAsync(binaryFile);
  590. return new Uint8Array(response);
  591. } catch {
  592. // Fall back to getBinarySync below;
  593. }
  594. }
  595. // Otherwise, getBinarySync should be able to get it synchronously
  596. return getBinarySync(binaryFile);
  597. }
  598. async function instantiateArrayBuffer(binaryFile, imports) {
  599. try {
  600. var binary = await getWasmBinary(binaryFile);
  601. var instance = await WebAssembly.instantiate(binary, imports);
  602. return instance;
  603. } catch (reason) {
  604. err(`failed to asynchronously prepare wasm: ${reason}`);
  605. // Warn on some common problems.
  606. if (isFileURI(wasmBinaryFile)) {
  607. 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`);
  608. }
  609. abort(reason);
  610. }
  611. }
  612. async function instantiateAsync(binary, binaryFile, imports) {
  613. if (!binary && typeof WebAssembly.instantiateStreaming == 'function'
  614. // Don't use streaming for file:// delivered objects in a webview, fetch them synchronously.
  615. && !isFileURI(binaryFile)
  616. // Avoid instantiateStreaming() on Node.js environment for now, as while
  617. // Node.js v18.1.0 implements it, it does not have a full fetch()
  618. // implementation yet.
  619. //
  620. // Reference:
  621. // https://github.com/emscripten-core/emscripten/pull/16917
  622. && !ENVIRONMENT_IS_NODE
  623. ) {
  624. try {
  625. var response = fetch(binaryFile, { credentials: 'same-origin' });
  626. var instantiationResult = await WebAssembly.instantiateStreaming(response, imports);
  627. return instantiationResult;
  628. } catch (reason) {
  629. // We expect the most common failure cause to be a bad MIME type for the binary,
  630. // in which case falling back to ArrayBuffer instantiation should work.
  631. err(`wasm streaming compile failed: ${reason}`);
  632. err('falling back to ArrayBuffer instantiation');
  633. // fall back of instantiateArrayBuffer below
  634. };
  635. }
  636. return instantiateArrayBuffer(binaryFile, imports);
  637. }
  638. function getWasmImports() {
  639. // prepare imports
  640. return {
  641. 'env': wasmImports,
  642. 'wasi_snapshot_preview1': wasmImports,
  643. }
  644. }
  645. // Create the wasm instance.
  646. // Receives the wasm imports, returns the exports.
  647. async function createWasm() {
  648. // Load the wasm module and create an instance of using native support in the JS engine.
  649. // handle a generated wasm instance, receiving its exports and
  650. // performing other necessary setup
  651. /** @param {WebAssembly.Module=} module*/
  652. function receiveInstance(instance, module) {
  653. wasmExports = instance.exports;
  654. wasmMemory = wasmExports['memory'];
  655. assert(wasmMemory, 'memory not found in wasm exports');
  656. updateMemoryViews();
  657. wasmTable = wasmExports['__indirect_function_table'];
  658. assert(wasmTable, 'table not found in wasm exports');
  659. removeRunDependency('wasm-instantiate');
  660. return wasmExports;
  661. }
  662. // wait for the pthread pool (if any)
  663. addRunDependency('wasm-instantiate');
  664. // Prefer streaming instantiation if available.
  665. // Async compilation can be confusing when an error on the page overwrites Module
  666. // (for example, if the order of elements is wrong, and the one defining Module is
  667. // later), so we save Module and check it later.
  668. var trueModule = Module;
  669. function receiveInstantiationResult(result) {
  670. // 'result' is a ResultObject object which has both the module and instance.
  671. // receiveInstance() will swap in the exports (to Module.asm) so they can be called
  672. assert(Module === trueModule, 'the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?');
  673. trueModule = null;
  674. // 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.
  675. // When the regression is fixed, can restore the above PTHREADS-enabled path.
  676. return receiveInstance(result['instance']);
  677. }
  678. var info = getWasmImports();
  679. // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback
  680. // to manually instantiate the Wasm module themselves. This allows pages to
  681. // run the instantiation parallel to any other async startup actions they are
  682. // performing.
  683. // Also pthreads and wasm workers initialize the wasm instance through this
  684. // path.
  685. if (Module['instantiateWasm']) {
  686. return new Promise((resolve, reject) => {
  687. try {
  688. Module['instantiateWasm'](info, (mod, inst) => {
  689. receiveInstance(mod, inst);
  690. resolve(mod.exports);
  691. });
  692. } catch(e) {
  693. err(`Module.instantiateWasm callback failed with error: ${e}`);
  694. reject(e);
  695. }
  696. });
  697. }
  698. wasmBinaryFile ??= findWasmBinary();
  699. var result = await instantiateAsync(wasmBinary, wasmBinaryFile, info);
  700. var exports = receiveInstantiationResult(result);
  701. return exports;
  702. }
  703. // === Body ===
  704. var ASM_CONSTS = {
  705. 151192: () => { if (document.fullscreenElement) return 1; },
  706. 151238: () => { return document.getElementById('canvas').width; },
  707. 151290: () => { return parseInt(document.getElementById('canvas').style.width); },
  708. 151358: () => { document.exitFullscreen(); },
  709. 151385: () => { setTimeout(function() { Module.requestFullscreen(false, false); }, 100); },
  710. 151458: () => { if (document.fullscreenElement) return 1; },
  711. 151504: () => { return document.getElementById('canvas').width; },
  712. 151556: () => { return screen.width; },
  713. 151581: () => { document.exitFullscreen(); },
  714. 151608: () => { setTimeout(function() { Module.requestFullscreen(false, true); setTimeout(function() { canvas.style.width="unset"; }, 100); }, 100); },
  715. 151741: () => { return window.innerWidth; },
  716. 151767: () => { return window.innerHeight; },
  717. 151794: () => { if (document.fullscreenElement) return 1; },
  718. 151840: () => { return document.getElementById('canvas').width; },
  719. 151892: () => { return parseInt(document.getElementById('canvas').style.width); },
  720. 151960: () => { if (document.fullscreenElement) return 1; },
  721. 152006: () => { return document.getElementById('canvas').width; },
  722. 152058: () => { return screen.width; },
  723. 152083: () => { return window.innerWidth; },
  724. 152109: () => { return window.innerHeight; },
  725. 152136: () => { if (document.fullscreenElement) return 1; },
  726. 152182: () => { return document.getElementById('canvas').width; },
  727. 152234: () => { return screen.width; },
  728. 152259: () => { document.exitFullscreen(); },
  729. 152286: () => { if (document.fullscreenElement) return 1; },
  730. 152332: () => { return document.getElementById('canvas').width; },
  731. 152384: () => { return parseInt(document.getElementById('canvas').style.width); },
  732. 152452: () => { document.exitFullscreen(); },
  733. 152479: ($0) => { document.getElementById('canvas').style.opacity = $0; },
  734. 152537: () => { return screen.width; },
  735. 152562: () => { return screen.height; },
  736. 152588: () => { return window.screenX; },
  737. 152615: () => { return window.screenY; },
  738. 152642: ($0) => { navigator.clipboard.writeText(UTF8ToString($0)); },
  739. 152695: ($0) => { document.getElementById("canvas").style.cursor = UTF8ToString($0); },
  740. 152766: () => { document.getElementById('canvas').style.cursor = 'none'; },
  741. 152823: ($0, $1, $2, $3) => { try { navigator.getGamepads()[$0].vibrationActuator.playEffect('dual-rumble', { startDelay: 0, duration: $3, weakMagnitude: $1, strongMagnitude: $2 }); } catch (e) { try { navigator.getGamepads()[$0].hapticActuators[0].pulse($2, $3); } catch (e) { } } },
  742. 153079: ($0) => { document.getElementById('canvas').style.cursor = UTF8ToString($0); },
  743. 153150: () => { if (document.fullscreenElement) return 1; },
  744. 153196: () => { return window.innerWidth; },
  745. 153222: () => { return window.innerHeight; },
  746. 153249: () => { if (document.pointerLockElement) return 1; }
  747. };
  748. // end include: preamble.js
  749. class ExitStatus {
  750. name = 'ExitStatus';
  751. constructor(status) {
  752. this.message = `Program terminated with exit(${status})`;
  753. this.status = status;
  754. }
  755. }
  756. var callRuntimeCallbacks = (callbacks) => {
  757. while (callbacks.length > 0) {
  758. // Pass the module as the first argument.
  759. callbacks.shift()(Module);
  760. }
  761. };
  762. var onPostRuns = [];
  763. var addOnPostRun = (cb) => onPostRuns.unshift(cb);
  764. var onPreRuns = [];
  765. var addOnPreRun = (cb) => onPreRuns.unshift(cb);
  766. /**
  767. * @param {number} ptr
  768. * @param {string} type
  769. */
  770. function getValue(ptr, type = 'i8') {
  771. if (type.endsWith('*')) type = '*';
  772. switch (type) {
  773. case 'i1': return HEAP8[ptr];
  774. case 'i8': return HEAP8[ptr];
  775. case 'i16': return HEAP16[((ptr)>>1)];
  776. case 'i32': return HEAP32[((ptr)>>2)];
  777. case 'i64': return HEAP64[((ptr)>>3)];
  778. case 'float': return HEAPF32[((ptr)>>2)];
  779. case 'double': return HEAPF64[((ptr)>>3)];
  780. case '*': return HEAPU32[((ptr)>>2)];
  781. default: abort(`invalid type for getValue: ${type}`);
  782. }
  783. }
  784. var noExitRuntime = Module['noExitRuntime'] || true;
  785. var ptrToString = (ptr) => {
  786. assert(typeof ptr === 'number');
  787. // With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned.
  788. ptr >>>= 0;
  789. return '0x' + ptr.toString(16).padStart(8, '0');
  790. };
  791. /**
  792. * @param {number} ptr
  793. * @param {number} value
  794. * @param {string} type
  795. */
  796. function setValue(ptr, value, type = 'i8') {
  797. if (type.endsWith('*')) type = '*';
  798. switch (type) {
  799. case 'i1': HEAP8[ptr] = value; break;
  800. case 'i8': HEAP8[ptr] = value; break;
  801. case 'i16': HEAP16[((ptr)>>1)] = value; break;
  802. case 'i32': HEAP32[((ptr)>>2)] = value; break;
  803. case 'i64': HEAP64[((ptr)>>3)] = BigInt(value); break;
  804. case 'float': HEAPF32[((ptr)>>2)] = value; break;
  805. case 'double': HEAPF64[((ptr)>>3)] = value; break;
  806. case '*': HEAPU32[((ptr)>>2)] = value; break;
  807. default: abort(`invalid type for setValue: ${type}`);
  808. }
  809. }
  810. var stackRestore = (val) => __emscripten_stack_restore(val);
  811. var stackSave = () => _emscripten_stack_get_current();
  812. var warnOnce = (text) => {
  813. warnOnce.shown ||= {};
  814. if (!warnOnce.shown[text]) {
  815. warnOnce.shown[text] = 1;
  816. if (ENVIRONMENT_IS_NODE) text = 'warning: ' + text;
  817. err(text);
  818. }
  819. };
  820. var UTF8Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder() : undefined;
  821. /**
  822. * Given a pointer 'idx' to a null-terminated UTF8-encoded string in the given
  823. * array that contains uint8 values, returns a copy of that string as a
  824. * Javascript String object.
  825. * heapOrArray is either a regular array, or a JavaScript typed array view.
  826. * @param {number=} idx
  827. * @param {number=} maxBytesToRead
  828. * @return {string}
  829. */
  830. var UTF8ArrayToString = (heapOrArray, idx = 0, maxBytesToRead = NaN) => {
  831. var endIdx = idx + maxBytesToRead;
  832. var endPtr = idx;
  833. // TextDecoder needs to know the byte length in advance, it doesn't stop on
  834. // null terminator by itself. Also, use the length info to avoid running tiny
  835. // strings through TextDecoder, since .subarray() allocates garbage.
  836. // (As a tiny code save trick, compare endPtr against endIdx using a negation,
  837. // so that undefined/NaN means Infinity)
  838. while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr;
  839. if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) {
  840. return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr));
  841. }
  842. var str = '';
  843. // If building with TextDecoder, we have already computed the string length
  844. // above, so test loop end condition against that
  845. while (idx < endPtr) {
  846. // For UTF8 byte structure, see:
  847. // http://en.wikipedia.org/wiki/UTF-8#Description
  848. // https://www.ietf.org/rfc/rfc2279.txt
  849. // https://tools.ietf.org/html/rfc3629
  850. var u0 = heapOrArray[idx++];
  851. if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; }
  852. var u1 = heapOrArray[idx++] & 63;
  853. if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; }
  854. var u2 = heapOrArray[idx++] & 63;
  855. if ((u0 & 0xF0) == 0xE0) {
  856. u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
  857. } else {
  858. 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!');
  859. u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heapOrArray[idx++] & 63);
  860. }
  861. if (u0 < 0x10000) {
  862. str += String.fromCharCode(u0);
  863. } else {
  864. var ch = u0 - 0x10000;
  865. str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
  866. }
  867. }
  868. return str;
  869. };
  870. /**
  871. * Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the
  872. * emscripten HEAP, returns a copy of that string as a Javascript String object.
  873. *
  874. * @param {number} ptr
  875. * @param {number=} maxBytesToRead - An optional length that specifies the
  876. * maximum number of bytes to read. You can omit this parameter to scan the
  877. * string until the first 0 byte. If maxBytesToRead is passed, and the string
  878. * at [ptr, ptr+maxBytesToReadr[ contains a null byte in the middle, then the
  879. * string will cut short at that byte index (i.e. maxBytesToRead will not
  880. * produce a string of exact length [ptr, ptr+maxBytesToRead[) N.B. mixing
  881. * frequent uses of UTF8ToString() with and without maxBytesToRead may throw
  882. * JS JIT optimizations off, so it is worth to consider consistently using one
  883. * @return {string}
  884. */
  885. var UTF8ToString = (ptr, maxBytesToRead) => {
  886. assert(typeof ptr == 'number', `UTF8ToString expects a number (got ${typeof ptr})`);
  887. return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : '';
  888. };
  889. var ___assert_fail = (condition, filename, line, func) =>
  890. abort(`Assertion failed: ${UTF8ToString(condition)}, at: ` + [filename ? UTF8ToString(filename) : 'unknown filename', line, func ? UTF8ToString(func) : 'unknown function']);
  891. var PATH = {
  892. isAbs:(path) => path.charAt(0) === '/',
  893. splitPath:(filename) => {
  894. var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
  895. return splitPathRe.exec(filename).slice(1);
  896. },
  897. normalizeArray:(parts, allowAboveRoot) => {
  898. // if the path tries to go above the root, `up` ends up > 0
  899. var up = 0;
  900. for (var i = parts.length - 1; i >= 0; i--) {
  901. var last = parts[i];
  902. if (last === '.') {
  903. parts.splice(i, 1);
  904. } else if (last === '..') {
  905. parts.splice(i, 1);
  906. up++;
  907. } else if (up) {
  908. parts.splice(i, 1);
  909. up--;
  910. }
  911. }
  912. // if the path is allowed to go above the root, restore leading ..s
  913. if (allowAboveRoot) {
  914. for (; up; up--) {
  915. parts.unshift('..');
  916. }
  917. }
  918. return parts;
  919. },
  920. normalize:(path) => {
  921. var isAbsolute = PATH.isAbs(path),
  922. trailingSlash = path.slice(-1) === '/';
  923. // Normalize the path
  924. path = PATH.normalizeArray(path.split('/').filter((p) => !!p), !isAbsolute).join('/');
  925. if (!path && !isAbsolute) {
  926. path = '.';
  927. }
  928. if (path && trailingSlash) {
  929. path += '/';
  930. }
  931. return (isAbsolute ? '/' : '') + path;
  932. },
  933. dirname:(path) => {
  934. var result = PATH.splitPath(path),
  935. root = result[0],
  936. dir = result[1];
  937. if (!root && !dir) {
  938. // No dirname whatsoever
  939. return '.';
  940. }
  941. if (dir) {
  942. // It has a dirname, strip trailing slash
  943. dir = dir.slice(0, -1);
  944. }
  945. return root + dir;
  946. },
  947. basename:(path) => path && path.match(/([^\/]+|\/)\/*$/)[1],
  948. join:(...paths) => PATH.normalize(paths.join('/')),
  949. join2:(l, r) => PATH.normalize(l + '/' + r),
  950. };
  951. var initRandomFill = () => {
  952. // This block is not needed on v19+ since crypto.getRandomValues is builtin
  953. if (ENVIRONMENT_IS_NODE) {
  954. var nodeCrypto = require('crypto');
  955. return (view) => nodeCrypto.randomFillSync(view);
  956. }
  957. return (view) => crypto.getRandomValues(view);
  958. };
  959. var randomFill = (view) => {
  960. // Lazily init on the first invocation.
  961. (randomFill = initRandomFill())(view);
  962. };
  963. var PATH_FS = {
  964. resolve:(...args) => {
  965. var resolvedPath = '',
  966. resolvedAbsolute = false;
  967. for (var i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) {
  968. var path = (i >= 0) ? args[i] : FS.cwd();
  969. // Skip empty and invalid entries
  970. if (typeof path != 'string') {
  971. throw new TypeError('Arguments to path.resolve must be strings');
  972. } else if (!path) {
  973. return ''; // an invalid portion invalidates the whole thing
  974. }
  975. resolvedPath = path + '/' + resolvedPath;
  976. resolvedAbsolute = PATH.isAbs(path);
  977. }
  978. // At this point the path should be resolved to a full absolute path, but
  979. // handle relative paths to be safe (might happen when process.cwd() fails)
  980. resolvedPath = PATH.normalizeArray(resolvedPath.split('/').filter((p) => !!p), !resolvedAbsolute).join('/');
  981. return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
  982. },
  983. relative:(from, to) => {
  984. from = PATH_FS.resolve(from).slice(1);
  985. to = PATH_FS.resolve(to).slice(1);
  986. function trim(arr) {
  987. var start = 0;
  988. for (; start < arr.length; start++) {
  989. if (arr[start] !== '') break;
  990. }
  991. var end = arr.length - 1;
  992. for (; end >= 0; end--) {
  993. if (arr[end] !== '') break;
  994. }
  995. if (start > end) return [];
  996. return arr.slice(start, end - start + 1);
  997. }
  998. var fromParts = trim(from.split('/'));
  999. var toParts = trim(to.split('/'));
  1000. var length = Math.min(fromParts.length, toParts.length);
  1001. var samePartsLength = length;
  1002. for (var i = 0; i < length; i++) {
  1003. if (fromParts[i] !== toParts[i]) {
  1004. samePartsLength = i;
  1005. break;
  1006. }
  1007. }
  1008. var outputParts = [];
  1009. for (var i = samePartsLength; i < fromParts.length; i++) {
  1010. outputParts.push('..');
  1011. }
  1012. outputParts = outputParts.concat(toParts.slice(samePartsLength));
  1013. return outputParts.join('/');
  1014. },
  1015. };
  1016. var FS_stdin_getChar_buffer = [];
  1017. var lengthBytesUTF8 = (str) => {
  1018. var len = 0;
  1019. for (var i = 0; i < str.length; ++i) {
  1020. // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code
  1021. // unit, not a Unicode code point of the character! So decode
  1022. // UTF16->UTF32->UTF8.
  1023. // See http://unicode.org/faq/utf_bom.html#utf16-3
  1024. var c = str.charCodeAt(i); // possibly a lead surrogate
  1025. if (c <= 0x7F) {
  1026. len++;
  1027. } else if (c <= 0x7FF) {
  1028. len += 2;
  1029. } else if (c >= 0xD800 && c <= 0xDFFF) {
  1030. len += 4; ++i;
  1031. } else {
  1032. len += 3;
  1033. }
  1034. }
  1035. return len;
  1036. };
  1037. var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
  1038. assert(typeof str === 'string', `stringToUTF8Array expects a string (got ${typeof str})`);
  1039. // Parameter maxBytesToWrite is not optional. Negative values, 0, null,
  1040. // undefined and false each don't write out any bytes.
  1041. if (!(maxBytesToWrite > 0))
  1042. return 0;
  1043. var startIdx = outIdx;
  1044. var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator.
  1045. for (var i = 0; i < str.length; ++i) {
  1046. // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code
  1047. // unit, not a Unicode code point of the character! So decode
  1048. // UTF16->UTF32->UTF8.
  1049. // See http://unicode.org/faq/utf_bom.html#utf16-3
  1050. // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description
  1051. // and https://www.ietf.org/rfc/rfc2279.txt
  1052. // and https://tools.ietf.org/html/rfc3629
  1053. var u = str.charCodeAt(i); // possibly a lead surrogate
  1054. if (u >= 0xD800 && u <= 0xDFFF) {
  1055. var u1 = str.charCodeAt(++i);
  1056. u = 0x10000 + ((u & 0x3FF) << 10) | (u1 & 0x3FF);
  1057. }
  1058. if (u <= 0x7F) {
  1059. if (outIdx >= endIdx) break;
  1060. heap[outIdx++] = u;
  1061. } else if (u <= 0x7FF) {
  1062. if (outIdx + 1 >= endIdx) break;
  1063. heap[outIdx++] = 0xC0 | (u >> 6);
  1064. heap[outIdx++] = 0x80 | (u & 63);
  1065. } else if (u <= 0xFFFF) {
  1066. if (outIdx + 2 >= endIdx) break;
  1067. heap[outIdx++] = 0xE0 | (u >> 12);
  1068. heap[outIdx++] = 0x80 | ((u >> 6) & 63);
  1069. heap[outIdx++] = 0x80 | (u & 63);
  1070. } else {
  1071. if (outIdx + 3 >= endIdx) break;
  1072. 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).');
  1073. heap[outIdx++] = 0xF0 | (u >> 18);
  1074. heap[outIdx++] = 0x80 | ((u >> 12) & 63);
  1075. heap[outIdx++] = 0x80 | ((u >> 6) & 63);
  1076. heap[outIdx++] = 0x80 | (u & 63);
  1077. }
  1078. }
  1079. // Null-terminate the pointer to the buffer.
  1080. heap[outIdx] = 0;
  1081. return outIdx - startIdx;
  1082. };
  1083. /** @type {function(string, boolean=, number=)} */
  1084. var intArrayFromString = (stringy, dontAddNull, length) => {
  1085. var len = length > 0 ? length : lengthBytesUTF8(stringy)+1;
  1086. var u8array = new Array(len);
  1087. var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length);
  1088. if (dontAddNull) u8array.length = numBytesWritten;
  1089. return u8array;
  1090. };
  1091. var FS_stdin_getChar = () => {
  1092. if (!FS_stdin_getChar_buffer.length) {
  1093. var result = null;
  1094. if (ENVIRONMENT_IS_NODE) {
  1095. // we will read data by chunks of BUFSIZE
  1096. var BUFSIZE = 256;
  1097. var buf = Buffer.alloc(BUFSIZE);
  1098. var bytesRead = 0;
  1099. // For some reason we must suppress a closure warning here, even though
  1100. // fd definitely exists on process.stdin, and is even the proper way to
  1101. // get the fd of stdin,
  1102. // https://github.com/nodejs/help/issues/2136#issuecomment-523649904
  1103. // This started to happen after moving this logic out of library_tty.js,
  1104. // so it is related to the surrounding code in some unclear manner.
  1105. /** @suppress {missingProperties} */
  1106. var fd = process.stdin.fd;
  1107. try {
  1108. bytesRead = fs.readSync(fd, buf, 0, BUFSIZE);
  1109. } catch(e) {
  1110. // Cross-platform differences: on Windows, reading EOF throws an
  1111. // exception, but on other OSes, reading EOF returns 0. Uniformize
  1112. // behavior by treating the EOF exception to return 0.
  1113. if (e.toString().includes('EOF')) bytesRead = 0;
  1114. else throw e;
  1115. }
  1116. if (bytesRead > 0) {
  1117. result = buf.slice(0, bytesRead).toString('utf-8');
  1118. }
  1119. } else
  1120. if (typeof window != 'undefined' &&
  1121. typeof window.prompt == 'function') {
  1122. // Browser.
  1123. result = window.prompt('Input: '); // returns null on cancel
  1124. if (result !== null) {
  1125. result += '\n';
  1126. }
  1127. } else
  1128. {}
  1129. if (!result) {
  1130. return null;
  1131. }
  1132. FS_stdin_getChar_buffer = intArrayFromString(result, true);
  1133. }
  1134. return FS_stdin_getChar_buffer.shift();
  1135. };
  1136. var TTY = {
  1137. ttys:[],
  1138. init() {
  1139. // https://github.com/emscripten-core/emscripten/pull/1555
  1140. // if (ENVIRONMENT_IS_NODE) {
  1141. // // currently, FS.init does not distinguish if process.stdin is a file or TTY
  1142. // // device, it always assumes it's a TTY device. because of this, we're forcing
  1143. // // process.stdin to UTF8 encoding to at least make stdin reading compatible
  1144. // // with text files until FS.init can be refactored.
  1145. // process.stdin.setEncoding('utf8');
  1146. // }
  1147. },
  1148. shutdown() {
  1149. // https://github.com/emscripten-core/emscripten/pull/1555
  1150. // if (ENVIRONMENT_IS_NODE) {
  1151. // // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)?
  1152. // // 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
  1153. // // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists?
  1154. // // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle
  1155. // // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call
  1156. // process.stdin.pause();
  1157. // }
  1158. },
  1159. register(dev, ops) {
  1160. TTY.ttys[dev] = { input: [], output: [], ops: ops };
  1161. FS.registerDevice(dev, TTY.stream_ops);
  1162. },
  1163. stream_ops:{
  1164. open(stream) {
  1165. var tty = TTY.ttys[stream.node.rdev];
  1166. if (!tty) {
  1167. throw new FS.ErrnoError(43);
  1168. }
  1169. stream.tty = tty;
  1170. stream.seekable = false;
  1171. },
  1172. close(stream) {
  1173. // flush any pending line data
  1174. stream.tty.ops.fsync(stream.tty);
  1175. },
  1176. fsync(stream) {
  1177. stream.tty.ops.fsync(stream.tty);
  1178. },
  1179. read(stream, buffer, offset, length, pos /* ignored */) {
  1180. if (!stream.tty || !stream.tty.ops.get_char) {
  1181. throw new FS.ErrnoError(60);
  1182. }
  1183. var bytesRead = 0;
  1184. for (var i = 0; i < length; i++) {
  1185. var result;
  1186. try {
  1187. result = stream.tty.ops.get_char(stream.tty);
  1188. } catch (e) {
  1189. throw new FS.ErrnoError(29);
  1190. }
  1191. if (result === undefined && bytesRead === 0) {
  1192. throw new FS.ErrnoError(6);
  1193. }
  1194. if (result === null || result === undefined) break;
  1195. bytesRead++;
  1196. buffer[offset+i] = result;
  1197. }
  1198. if (bytesRead) {
  1199. stream.node.atime = Date.now();
  1200. }
  1201. return bytesRead;
  1202. },
  1203. write(stream, buffer, offset, length, pos) {
  1204. if (!stream.tty || !stream.tty.ops.put_char) {
  1205. throw new FS.ErrnoError(60);
  1206. }
  1207. try {
  1208. for (var i = 0; i < length; i++) {
  1209. stream.tty.ops.put_char(stream.tty, buffer[offset+i]);
  1210. }
  1211. } catch (e) {
  1212. throw new FS.ErrnoError(29);
  1213. }
  1214. if (length) {
  1215. stream.node.mtime = stream.node.ctime = Date.now();
  1216. }
  1217. return i;
  1218. },
  1219. },
  1220. default_tty_ops:{
  1221. get_char(tty) {
  1222. return FS_stdin_getChar();
  1223. },
  1224. put_char(tty, val) {
  1225. if (val === null || val === 10) {
  1226. out(UTF8ArrayToString(tty.output));
  1227. tty.output = [];
  1228. } else {
  1229. if (val != 0) tty.output.push(val); // val == 0 would cut text output off in the middle.
  1230. }
  1231. },
  1232. fsync(tty) {
  1233. if (tty.output?.length > 0) {
  1234. out(UTF8ArrayToString(tty.output));
  1235. tty.output = [];
  1236. }
  1237. },
  1238. ioctl_tcgets(tty) {
  1239. // typical setting
  1240. return {
  1241. c_iflag: 25856,
  1242. c_oflag: 5,
  1243. c_cflag: 191,
  1244. c_lflag: 35387,
  1245. c_cc: [
  1246. 0x03, 0x1c, 0x7f, 0x15, 0x04, 0x00, 0x01, 0x00, 0x11, 0x13, 0x1a, 0x00,
  1247. 0x12, 0x0f, 0x17, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1248. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1249. ]
  1250. };
  1251. },
  1252. ioctl_tcsets(tty, optional_actions, data) {
  1253. // currently just ignore
  1254. return 0;
  1255. },
  1256. ioctl_tiocgwinsz(tty) {
  1257. return [24, 80];
  1258. },
  1259. },
  1260. default_tty1_ops:{
  1261. put_char(tty, val) {
  1262. if (val === null || val === 10) {
  1263. err(UTF8ArrayToString(tty.output));
  1264. tty.output = [];
  1265. } else {
  1266. if (val != 0) tty.output.push(val);
  1267. }
  1268. },
  1269. fsync(tty) {
  1270. if (tty.output?.length > 0) {
  1271. err(UTF8ArrayToString(tty.output));
  1272. tty.output = [];
  1273. }
  1274. },
  1275. },
  1276. };
  1277. var zeroMemory = (address, size) => {
  1278. HEAPU8.fill(0, address, address + size);
  1279. };
  1280. var alignMemory = (size, alignment) => {
  1281. assert(alignment, "alignment argument is required");
  1282. return Math.ceil(size / alignment) * alignment;
  1283. };
  1284. var mmapAlloc = (size) => {
  1285. abort('internal error: mmapAlloc called but `emscripten_builtin_memalign` native symbol not exported');
  1286. };
  1287. var MEMFS = {
  1288. ops_table:null,
  1289. mount(mount) {
  1290. return MEMFS.createNode(null, '/', 16895, 0);
  1291. },
  1292. createNode(parent, name, mode, dev) {
  1293. if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
  1294. // no supported
  1295. throw new FS.ErrnoError(63);
  1296. }
  1297. MEMFS.ops_table ||= {
  1298. dir: {
  1299. node: {
  1300. getattr: MEMFS.node_ops.getattr,
  1301. setattr: MEMFS.node_ops.setattr,
  1302. lookup: MEMFS.node_ops.lookup,
  1303. mknod: MEMFS.node_ops.mknod,
  1304. rename: MEMFS.node_ops.rename,
  1305. unlink: MEMFS.node_ops.unlink,
  1306. rmdir: MEMFS.node_ops.rmdir,
  1307. readdir: MEMFS.node_ops.readdir,
  1308. symlink: MEMFS.node_ops.symlink
  1309. },
  1310. stream: {
  1311. llseek: MEMFS.stream_ops.llseek
  1312. }
  1313. },
  1314. file: {
  1315. node: {
  1316. getattr: MEMFS.node_ops.getattr,
  1317. setattr: MEMFS.node_ops.setattr
  1318. },
  1319. stream: {
  1320. llseek: MEMFS.stream_ops.llseek,
  1321. read: MEMFS.stream_ops.read,
  1322. write: MEMFS.stream_ops.write,
  1323. allocate: MEMFS.stream_ops.allocate,
  1324. mmap: MEMFS.stream_ops.mmap,
  1325. msync: MEMFS.stream_ops.msync
  1326. }
  1327. },
  1328. link: {
  1329. node: {
  1330. getattr: MEMFS.node_ops.getattr,
  1331. setattr: MEMFS.node_ops.setattr,
  1332. readlink: MEMFS.node_ops.readlink
  1333. },
  1334. stream: {}
  1335. },
  1336. chrdev: {
  1337. node: {
  1338. getattr: MEMFS.node_ops.getattr,
  1339. setattr: MEMFS.node_ops.setattr
  1340. },
  1341. stream: FS.chrdev_stream_ops
  1342. }
  1343. };
  1344. var node = FS.createNode(parent, name, mode, dev);
  1345. if (FS.isDir(node.mode)) {
  1346. node.node_ops = MEMFS.ops_table.dir.node;
  1347. node.stream_ops = MEMFS.ops_table.dir.stream;
  1348. node.contents = {};
  1349. } else if (FS.isFile(node.mode)) {
  1350. node.node_ops = MEMFS.ops_table.file.node;
  1351. node.stream_ops = MEMFS.ops_table.file.stream;
  1352. node.usedBytes = 0; // The actual number of bytes used in the typed array, as opposed to contents.length which gives the whole capacity.
  1353. // 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
  1354. // for performance, and used by default. However, typed arrays are not resizable like normal JS arrays are, so there is a small disk size
  1355. // penalty involved for appending file writes that continuously grow a file similar to std::vector capacity vs used -scheme.
  1356. node.contents = null;
  1357. } else if (FS.isLink(node.mode)) {
  1358. node.node_ops = MEMFS.ops_table.link.node;
  1359. node.stream_ops = MEMFS.ops_table.link.stream;
  1360. } else if (FS.isChrdev(node.mode)) {
  1361. node.node_ops = MEMFS.ops_table.chrdev.node;
  1362. node.stream_ops = MEMFS.ops_table.chrdev.stream;
  1363. }
  1364. node.atime = node.mtime = node.ctime = Date.now();
  1365. // add the new node to the parent
  1366. if (parent) {
  1367. parent.contents[name] = node;
  1368. parent.atime = parent.mtime = parent.ctime = node.atime;
  1369. }
  1370. return node;
  1371. },
  1372. getFileDataAsTypedArray(node) {
  1373. if (!node.contents) return new Uint8Array(0);
  1374. if (node.contents.subarray) return node.contents.subarray(0, node.usedBytes); // Make sure to not return excess unused bytes.
  1375. return new Uint8Array(node.contents);
  1376. },
  1377. expandFileStorage(node, newCapacity) {
  1378. var prevCapacity = node.contents ? node.contents.length : 0;
  1379. if (prevCapacity >= newCapacity) return; // No need to expand, the storage was already large enough.
  1380. // Don't expand strictly to the given requested limit if it's only a very small increase, but instead geometrically grow capacity.
  1381. // For small filesizes (<1MB), perform size*2 geometric increase, but for large sizes, do a much more conservative size*1.125 increase to
  1382. // avoid overshooting the allocation cap by a very large margin.
  1383. var CAPACITY_DOUBLING_MAX = 1024 * 1024;
  1384. newCapacity = Math.max(newCapacity, (prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2.0 : 1.125)) >>> 0);
  1385. if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); // At minimum allocate 256b for each file when expanding.
  1386. var oldContents = node.contents;
  1387. node.contents = new Uint8Array(newCapacity); // Allocate new storage.
  1388. if (node.usedBytes > 0) node.contents.set(oldContents.subarray(0, node.usedBytes), 0); // Copy old data over to the new storage.
  1389. },
  1390. resizeFileStorage(node, newSize) {
  1391. if (node.usedBytes == newSize) return;
  1392. if (newSize == 0) {
  1393. node.contents = null; // Fully decommit when requesting a resize to zero.
  1394. node.usedBytes = 0;
  1395. } else {
  1396. var oldContents = node.contents;
  1397. node.contents = new Uint8Array(newSize); // Allocate new storage.
  1398. if (oldContents) {
  1399. node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))); // Copy old data over to the new storage.
  1400. }
  1401. node.usedBytes = newSize;
  1402. }
  1403. },
  1404. node_ops:{
  1405. getattr(node) {
  1406. var attr = {};
  1407. // device numbers reuse inode numbers.
  1408. attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
  1409. attr.ino = node.id;
  1410. attr.mode = node.mode;
  1411. attr.nlink = 1;
  1412. attr.uid = 0;
  1413. attr.gid = 0;
  1414. attr.rdev = node.rdev;
  1415. if (FS.isDir(node.mode)) {
  1416. attr.size = 4096;
  1417. } else if (FS.isFile(node.mode)) {
  1418. attr.size = node.usedBytes;
  1419. } else if (FS.isLink(node.mode)) {
  1420. attr.size = node.link.length;
  1421. } else {
  1422. attr.size = 0;
  1423. }
  1424. attr.atime = new Date(node.atime);
  1425. attr.mtime = new Date(node.mtime);
  1426. attr.ctime = new Date(node.ctime);
  1427. // NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize),
  1428. // but this is not required by the standard.
  1429. attr.blksize = 4096;
  1430. attr.blocks = Math.ceil(attr.size / attr.blksize);
  1431. return attr;
  1432. },
  1433. setattr(node, attr) {
  1434. for (const key of ["mode", "atime", "mtime", "ctime"]) {
  1435. if (attr[key] != null) {
  1436. node[key] = attr[key];
  1437. }
  1438. }
  1439. if (attr.size !== undefined) {
  1440. MEMFS.resizeFileStorage(node, attr.size);
  1441. }
  1442. },
  1443. lookup(parent, name) {
  1444. throw new FS.ErrnoError(44);
  1445. },
  1446. mknod(parent, name, mode, dev) {
  1447. return MEMFS.createNode(parent, name, mode, dev);
  1448. },
  1449. rename(old_node, new_dir, new_name) {
  1450. var new_node;
  1451. try {
  1452. new_node = FS.lookupNode(new_dir, new_name);
  1453. } catch (e) {}
  1454. if (new_node) {
  1455. if (FS.isDir(old_node.mode)) {
  1456. // if we're overwriting a directory at new_name, make sure it's empty.
  1457. for (var i in new_node.contents) {
  1458. throw new FS.ErrnoError(55);
  1459. }
  1460. }
  1461. FS.hashRemoveNode(new_node);
  1462. }
  1463. // do the internal rewiring
  1464. delete old_node.parent.contents[old_node.name];
  1465. new_dir.contents[new_name] = old_node;
  1466. old_node.name = new_name;
  1467. new_dir.ctime = new_dir.mtime = old_node.parent.ctime = old_node.parent.mtime = Date.now();
  1468. },
  1469. unlink(parent, name) {
  1470. delete parent.contents[name];
  1471. parent.ctime = parent.mtime = Date.now();
  1472. },
  1473. rmdir(parent, name) {
  1474. var node = FS.lookupNode(parent, name);
  1475. for (var i in node.contents) {
  1476. throw new FS.ErrnoError(55);
  1477. }
  1478. delete parent.contents[name];
  1479. parent.ctime = parent.mtime = Date.now();
  1480. },
  1481. readdir(node) {
  1482. return ['.', '..', ...Object.keys(node.contents)];
  1483. },
  1484. symlink(parent, newname, oldpath) {
  1485. var node = MEMFS.createNode(parent, newname, 0o777 | 40960, 0);
  1486. node.link = oldpath;
  1487. return node;
  1488. },
  1489. readlink(node) {
  1490. if (!FS.isLink(node.mode)) {
  1491. throw new FS.ErrnoError(28);
  1492. }
  1493. return node.link;
  1494. },
  1495. },
  1496. stream_ops:{
  1497. read(stream, buffer, offset, length, position) {
  1498. var contents = stream.node.contents;
  1499. if (position >= stream.node.usedBytes) return 0;
  1500. var size = Math.min(stream.node.usedBytes - position, length);
  1501. assert(size >= 0);
  1502. if (size > 8 && contents.subarray) { // non-trivial, and typed array
  1503. buffer.set(contents.subarray(position, position + size), offset);
  1504. } else {
  1505. for (var i = 0; i < size; i++) buffer[offset + i] = contents[position + i];
  1506. }
  1507. return size;
  1508. },
  1509. write(stream, buffer, offset, length, position, canOwn) {
  1510. // The data buffer should be a typed array view
  1511. assert(!(buffer instanceof ArrayBuffer));
  1512. if (!length) return 0;
  1513. var node = stream.node;
  1514. node.mtime = node.ctime = Date.now();
  1515. if (buffer.subarray && (!node.contents || node.contents.subarray)) { // This write is from a typed array to a typed array?
  1516. if (canOwn) {
  1517. assert(position === 0, 'canOwn must imply no weird position inside the file');
  1518. node.contents = buffer.subarray(offset, offset + length);
  1519. node.usedBytes = length;
  1520. return length;
  1521. } 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.
  1522. node.contents = buffer.slice(offset, offset + length);
  1523. node.usedBytes = length;
  1524. return length;
  1525. } else if (position + length <= node.usedBytes) { // Writing to an already allocated and used subrange of the file?
  1526. node.contents.set(buffer.subarray(offset, offset + length), position);
  1527. return length;
  1528. }
  1529. }
  1530. // Appending to an existing file and we need to reallocate, or source data did not come as a typed array.
  1531. MEMFS.expandFileStorage(node, position+length);
  1532. if (node.contents.subarray && buffer.subarray) {
  1533. // Use typed array write which is available.
  1534. node.contents.set(buffer.subarray(offset, offset + length), position);
  1535. } else {
  1536. for (var i = 0; i < length; i++) {
  1537. node.contents[position + i] = buffer[offset + i]; // Or fall back to manual write if not.
  1538. }
  1539. }
  1540. node.usedBytes = Math.max(node.usedBytes, position + length);
  1541. return length;
  1542. },
  1543. llseek(stream, offset, whence) {
  1544. var position = offset;
  1545. if (whence === 1) {
  1546. position += stream.position;
  1547. } else if (whence === 2) {
  1548. if (FS.isFile(stream.node.mode)) {
  1549. position += stream.node.usedBytes;
  1550. }
  1551. }
  1552. if (position < 0) {
  1553. throw new FS.ErrnoError(28);
  1554. }
  1555. return position;
  1556. },
  1557. allocate(stream, offset, length) {
  1558. MEMFS.expandFileStorage(stream.node, offset + length);
  1559. stream.node.usedBytes = Math.max(stream.node.usedBytes, offset + length);
  1560. },
  1561. mmap(stream, length, position, prot, flags) {
  1562. if (!FS.isFile(stream.node.mode)) {
  1563. throw new FS.ErrnoError(43);
  1564. }
  1565. var ptr;
  1566. var allocated;
  1567. var contents = stream.node.contents;
  1568. // Only make a new copy when MAP_PRIVATE is specified.
  1569. if (!(flags & 2) && contents && contents.buffer === HEAP8.buffer) {
  1570. // We can't emulate MAP_SHARED when the file is not backed by the
  1571. // buffer we're mapping to (e.g. the HEAP buffer).
  1572. allocated = false;
  1573. ptr = contents.byteOffset;
  1574. } else {
  1575. allocated = true;
  1576. ptr = mmapAlloc(length);
  1577. if (!ptr) {
  1578. throw new FS.ErrnoError(48);
  1579. }
  1580. if (contents) {
  1581. // Try to avoid unnecessary slices.
  1582. if (position > 0 || position + length < contents.length) {
  1583. if (contents.subarray) {
  1584. contents = contents.subarray(position, position + length);
  1585. } else {
  1586. contents = Array.prototype.slice.call(contents, position, position + length);
  1587. }
  1588. }
  1589. HEAP8.set(contents, ptr);
  1590. }
  1591. }
  1592. return { ptr, allocated };
  1593. },
  1594. msync(stream, buffer, offset, length, mmapFlags) {
  1595. MEMFS.stream_ops.write(stream, buffer, 0, length, offset, false);
  1596. // should we check if bytesWritten and length are the same?
  1597. return 0;
  1598. },
  1599. },
  1600. };
  1601. var asyncLoad = async (url) => {
  1602. var arrayBuffer = await readAsync(url);
  1603. assert(arrayBuffer, `Loading data file "${url}" failed (no arrayBuffer).`);
  1604. return new Uint8Array(arrayBuffer);
  1605. };
  1606. var FS_createDataFile = (parent, name, fileData, canRead, canWrite, canOwn) => {
  1607. FS.createDataFile(parent, name, fileData, canRead, canWrite, canOwn);
  1608. };
  1609. var preloadPlugins = Module['preloadPlugins'] || [];
  1610. var FS_handledByPreloadPlugin = (byteArray, fullname, finish, onerror) => {
  1611. // Ensure plugins are ready.
  1612. if (typeof Browser != 'undefined') Browser.init();
  1613. var handled = false;
  1614. preloadPlugins.forEach((plugin) => {
  1615. if (handled) return;
  1616. if (plugin['canHandle'](fullname)) {
  1617. plugin['handle'](byteArray, fullname, finish, onerror);
  1618. handled = true;
  1619. }
  1620. });
  1621. return handled;
  1622. };
  1623. var FS_createPreloadedFile = (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) => {
  1624. // TODO we should allow people to just pass in a complete filename instead
  1625. // of parent and name being that we just join them anyways
  1626. var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent;
  1627. var dep = getUniqueRunDependency(`cp ${fullname}`); // might have several active requests for the same fullname
  1628. function processData(byteArray) {
  1629. function finish(byteArray) {
  1630. preFinish?.();
  1631. if (!dontCreateFile) {
  1632. FS_createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
  1633. }
  1634. onload?.();
  1635. removeRunDependency(dep);
  1636. }
  1637. if (FS_handledByPreloadPlugin(byteArray, fullname, finish, () => {
  1638. onerror?.();
  1639. removeRunDependency(dep);
  1640. })) {
  1641. return;
  1642. }
  1643. finish(byteArray);
  1644. }
  1645. addRunDependency(dep);
  1646. if (typeof url == 'string') {
  1647. asyncLoad(url).then(processData, onerror);
  1648. } else {
  1649. processData(url);
  1650. }
  1651. };
  1652. var FS_modeStringToFlags = (str) => {
  1653. var flagModes = {
  1654. 'r': 0,
  1655. 'r+': 2,
  1656. 'w': 512 | 64 | 1,
  1657. 'w+': 512 | 64 | 2,
  1658. 'a': 1024 | 64 | 1,
  1659. 'a+': 1024 | 64 | 2,
  1660. };
  1661. var flags = flagModes[str];
  1662. if (typeof flags == 'undefined') {
  1663. throw new Error(`Unknown file open mode: ${str}`);
  1664. }
  1665. return flags;
  1666. };
  1667. var FS_getMode = (canRead, canWrite) => {
  1668. var mode = 0;
  1669. if (canRead) mode |= 292 | 73;
  1670. if (canWrite) mode |= 146;
  1671. return mode;
  1672. };
  1673. var strError = (errno) => UTF8ToString(_strerror(errno));
  1674. var ERRNO_CODES = {
  1675. 'EPERM': 63,
  1676. 'ENOENT': 44,
  1677. 'ESRCH': 71,
  1678. 'EINTR': 27,
  1679. 'EIO': 29,
  1680. 'ENXIO': 60,
  1681. 'E2BIG': 1,
  1682. 'ENOEXEC': 45,
  1683. 'EBADF': 8,
  1684. 'ECHILD': 12,
  1685. 'EAGAIN': 6,
  1686. 'EWOULDBLOCK': 6,
  1687. 'ENOMEM': 48,
  1688. 'EACCES': 2,
  1689. 'EFAULT': 21,
  1690. 'ENOTBLK': 105,
  1691. 'EBUSY': 10,
  1692. 'EEXIST': 20,
  1693. 'EXDEV': 75,
  1694. 'ENODEV': 43,
  1695. 'ENOTDIR': 54,
  1696. 'EISDIR': 31,
  1697. 'EINVAL': 28,
  1698. 'ENFILE': 41,
  1699. 'EMFILE': 33,
  1700. 'ENOTTY': 59,
  1701. 'ETXTBSY': 74,
  1702. 'EFBIG': 22,
  1703. 'ENOSPC': 51,
  1704. 'ESPIPE': 70,
  1705. 'EROFS': 69,
  1706. 'EMLINK': 34,
  1707. 'EPIPE': 64,
  1708. 'EDOM': 18,
  1709. 'ERANGE': 68,
  1710. 'ENOMSG': 49,
  1711. 'EIDRM': 24,
  1712. 'ECHRNG': 106,
  1713. 'EL2NSYNC': 156,
  1714. 'EL3HLT': 107,
  1715. 'EL3RST': 108,
  1716. 'ELNRNG': 109,
  1717. 'EUNATCH': 110,
  1718. 'ENOCSI': 111,
  1719. 'EL2HLT': 112,
  1720. 'EDEADLK': 16,
  1721. 'ENOLCK': 46,
  1722. 'EBADE': 113,
  1723. 'EBADR': 114,
  1724. 'EXFULL': 115,
  1725. 'ENOANO': 104,
  1726. 'EBADRQC': 103,
  1727. 'EBADSLT': 102,
  1728. 'EDEADLOCK': 16,
  1729. 'EBFONT': 101,
  1730. 'ENOSTR': 100,
  1731. 'ENODATA': 116,
  1732. 'ETIME': 117,
  1733. 'ENOSR': 118,
  1734. 'ENONET': 119,
  1735. 'ENOPKG': 120,
  1736. 'EREMOTE': 121,
  1737. 'ENOLINK': 47,
  1738. 'EADV': 122,
  1739. 'ESRMNT': 123,
  1740. 'ECOMM': 124,
  1741. 'EPROTO': 65,
  1742. 'EMULTIHOP': 36,
  1743. 'EDOTDOT': 125,
  1744. 'EBADMSG': 9,
  1745. 'ENOTUNIQ': 126,
  1746. 'EBADFD': 127,
  1747. 'EREMCHG': 128,
  1748. 'ELIBACC': 129,
  1749. 'ELIBBAD': 130,
  1750. 'ELIBSCN': 131,
  1751. 'ELIBMAX': 132,
  1752. 'ELIBEXEC': 133,
  1753. 'ENOSYS': 52,
  1754. 'ENOTEMPTY': 55,
  1755. 'ENAMETOOLONG': 37,
  1756. 'ELOOP': 32,
  1757. 'EOPNOTSUPP': 138,
  1758. 'EPFNOSUPPORT': 139,
  1759. 'ECONNRESET': 15,
  1760. 'ENOBUFS': 42,
  1761. 'EAFNOSUPPORT': 5,
  1762. 'EPROTOTYPE': 67,
  1763. 'ENOTSOCK': 57,
  1764. 'ENOPROTOOPT': 50,
  1765. 'ESHUTDOWN': 140,
  1766. 'ECONNREFUSED': 14,
  1767. 'EADDRINUSE': 3,
  1768. 'ECONNABORTED': 13,
  1769. 'ENETUNREACH': 40,
  1770. 'ENETDOWN': 38,
  1771. 'ETIMEDOUT': 73,
  1772. 'EHOSTDOWN': 142,
  1773. 'EHOSTUNREACH': 23,
  1774. 'EINPROGRESS': 26,
  1775. 'EALREADY': 7,
  1776. 'EDESTADDRREQ': 17,
  1777. 'EMSGSIZE': 35,
  1778. 'EPROTONOSUPPORT': 66,
  1779. 'ESOCKTNOSUPPORT': 137,
  1780. 'EADDRNOTAVAIL': 4,
  1781. 'ENETRESET': 39,
  1782. 'EISCONN': 30,
  1783. 'ENOTCONN': 53,
  1784. 'ETOOMANYREFS': 141,
  1785. 'EUSERS': 136,
  1786. 'EDQUOT': 19,
  1787. 'ESTALE': 72,
  1788. 'ENOTSUP': 138,
  1789. 'ENOMEDIUM': 148,
  1790. 'EILSEQ': 25,
  1791. 'EOVERFLOW': 61,
  1792. 'ECANCELED': 11,
  1793. 'ENOTRECOVERABLE': 56,
  1794. 'EOWNERDEAD': 62,
  1795. 'ESTRPIPE': 135,
  1796. };
  1797. var FS = {
  1798. root:null,
  1799. mounts:[],
  1800. devices:{
  1801. },
  1802. streams:[],
  1803. nextInode:1,
  1804. nameTable:null,
  1805. currentPath:"/",
  1806. initialized:false,
  1807. ignorePermissions:true,
  1808. ErrnoError:class extends Error {
  1809. name = 'ErrnoError';
  1810. // We set the `name` property to be able to identify `FS.ErrnoError`
  1811. // - the `name` is a standard ECMA-262 property of error objects. Kind of good to have it anyway.
  1812. // - when using PROXYFS, an error can come from an underlying FS
  1813. // as different FS objects have their own FS.ErrnoError each,
  1814. // the test `err instanceof FS.ErrnoError` won't detect an error coming from another filesystem, causing bugs.
  1815. // we'll use the reliable test `err.name == "ErrnoError"` instead
  1816. constructor(errno) {
  1817. super(runtimeInitialized ? strError(errno) : '');
  1818. this.errno = errno;
  1819. for (var key in ERRNO_CODES) {
  1820. if (ERRNO_CODES[key] === errno) {
  1821. this.code = key;
  1822. break;
  1823. }
  1824. }
  1825. }
  1826. },
  1827. filesystems:null,
  1828. syncFSRequests:0,
  1829. readFiles:{
  1830. },
  1831. FSStream:class {
  1832. shared = {};
  1833. get object() {
  1834. return this.node;
  1835. }
  1836. set object(val) {
  1837. this.node = val;
  1838. }
  1839. get isRead() {
  1840. return (this.flags & 2097155) !== 1;
  1841. }
  1842. get isWrite() {
  1843. return (this.flags & 2097155) !== 0;
  1844. }
  1845. get isAppend() {
  1846. return (this.flags & 1024);
  1847. }
  1848. get flags() {
  1849. return this.shared.flags;
  1850. }
  1851. set flags(val) {
  1852. this.shared.flags = val;
  1853. }
  1854. get position() {
  1855. return this.shared.position;
  1856. }
  1857. set position(val) {
  1858. this.shared.position = val;
  1859. }
  1860. },
  1861. FSNode:class {
  1862. node_ops = {};
  1863. stream_ops = {};
  1864. readMode = 292 | 73;
  1865. writeMode = 146;
  1866. mounted = null;
  1867. constructor(parent, name, mode, rdev) {
  1868. if (!parent) {
  1869. parent = this; // root node sets parent to itself
  1870. }
  1871. this.parent = parent;
  1872. this.mount = parent.mount;
  1873. this.id = FS.nextInode++;
  1874. this.name = name;
  1875. this.mode = mode;
  1876. this.rdev = rdev;
  1877. this.atime = this.mtime = this.ctime = Date.now();
  1878. }
  1879. get read() {
  1880. return (this.mode & this.readMode) === this.readMode;
  1881. }
  1882. set read(val) {
  1883. val ? this.mode |= this.readMode : this.mode &= ~this.readMode;
  1884. }
  1885. get write() {
  1886. return (this.mode & this.writeMode) === this.writeMode;
  1887. }
  1888. set write(val) {
  1889. val ? this.mode |= this.writeMode : this.mode &= ~this.writeMode;
  1890. }
  1891. get isFolder() {
  1892. return FS.isDir(this.mode);
  1893. }
  1894. get isDevice() {
  1895. return FS.isChrdev(this.mode);
  1896. }
  1897. },
  1898. lookupPath(path, opts = {}) {
  1899. if (!path) {
  1900. throw new FS.ErrnoError(44);
  1901. }
  1902. opts.follow_mount ??= true
  1903. if (!PATH.isAbs(path)) {
  1904. path = FS.cwd() + '/' + path;
  1905. }
  1906. // limit max consecutive symlinks to 40 (SYMLOOP_MAX).
  1907. linkloop: for (var nlinks = 0; nlinks < 40; nlinks++) {
  1908. // split the absolute path
  1909. var parts = path.split('/').filter((p) => !!p);
  1910. // start at the root
  1911. var current = FS.root;
  1912. var current_path = '/';
  1913. for (var i = 0; i < parts.length; i++) {
  1914. var islast = (i === parts.length-1);
  1915. if (islast && opts.parent) {
  1916. // stop resolving
  1917. break;
  1918. }
  1919. if (parts[i] === '.') {
  1920. continue;
  1921. }
  1922. if (parts[i] === '..') {
  1923. current_path = PATH.dirname(current_path);
  1924. current = current.parent;
  1925. continue;
  1926. }
  1927. current_path = PATH.join2(current_path, parts[i]);
  1928. try {
  1929. current = FS.lookupNode(current, parts[i]);
  1930. } catch (e) {
  1931. // if noent_okay is true, suppress a ENOENT in the last component
  1932. // and return an object with an undefined node. This is needed for
  1933. // resolving symlinks in the path when creating a file.
  1934. if ((e?.errno === 44) && islast && opts.noent_okay) {
  1935. return { path: current_path };
  1936. }
  1937. throw e;
  1938. }
  1939. // jump to the mount's root node if this is a mountpoint
  1940. if (FS.isMountpoint(current) && (!islast || opts.follow_mount)) {
  1941. current = current.mounted.root;
  1942. }
  1943. // by default, lookupPath will not follow a symlink if it is the final path component.
  1944. // setting opts.follow = true will override this behavior.
  1945. if (FS.isLink(current.mode) && (!islast || opts.follow)) {
  1946. if (!current.node_ops.readlink) {
  1947. throw new FS.ErrnoError(52);
  1948. }
  1949. var link = current.node_ops.readlink(current);
  1950. if (!PATH.isAbs(link)) {
  1951. link = PATH.dirname(current_path) + '/' + link;
  1952. }
  1953. path = link + '/' + parts.slice(i + 1).join('/');
  1954. continue linkloop;
  1955. }
  1956. }
  1957. return { path: current_path, node: current };
  1958. }
  1959. throw new FS.ErrnoError(32);
  1960. },
  1961. getPath(node) {
  1962. var path;
  1963. while (true) {
  1964. if (FS.isRoot(node)) {
  1965. var mount = node.mount.mountpoint;
  1966. if (!path) return mount;
  1967. return mount[mount.length-1] !== '/' ? `${mount}/${path}` : mount + path;
  1968. }
  1969. path = path ? `${node.name}/${path}` : node.name;
  1970. node = node.parent;
  1971. }
  1972. },
  1973. hashName(parentid, name) {
  1974. var hash = 0;
  1975. for (var i = 0; i < name.length; i++) {
  1976. hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
  1977. }
  1978. return ((parentid + hash) >>> 0) % FS.nameTable.length;
  1979. },
  1980. hashAddNode(node) {
  1981. var hash = FS.hashName(node.parent.id, node.name);
  1982. node.name_next = FS.nameTable[hash];
  1983. FS.nameTable[hash] = node;
  1984. },
  1985. hashRemoveNode(node) {
  1986. var hash = FS.hashName(node.parent.id, node.name);
  1987. if (FS.nameTable[hash] === node) {
  1988. FS.nameTable[hash] = node.name_next;
  1989. } else {
  1990. var current = FS.nameTable[hash];
  1991. while (current) {
  1992. if (current.name_next === node) {
  1993. current.name_next = node.name_next;
  1994. break;
  1995. }
  1996. current = current.name_next;
  1997. }
  1998. }
  1999. },
  2000. lookupNode(parent, name) {
  2001. var errCode = FS.mayLookup(parent);
  2002. if (errCode) {
  2003. throw new FS.ErrnoError(errCode);
  2004. }
  2005. var hash = FS.hashName(parent.id, name);
  2006. for (var node = FS.nameTable[hash]; node; node = node.name_next) {
  2007. var nodeName = node.name;
  2008. if (node.parent.id === parent.id && nodeName === name) {
  2009. return node;
  2010. }
  2011. }
  2012. // if we failed to find it in the cache, call into the VFS
  2013. return FS.lookup(parent, name);
  2014. },
  2015. createNode(parent, name, mode, rdev) {
  2016. assert(typeof parent == 'object')
  2017. var node = new FS.FSNode(parent, name, mode, rdev);
  2018. FS.hashAddNode(node);
  2019. return node;
  2020. },
  2021. destroyNode(node) {
  2022. FS.hashRemoveNode(node);
  2023. },
  2024. isRoot(node) {
  2025. return node === node.parent;
  2026. },
  2027. isMountpoint(node) {
  2028. return !!node.mounted;
  2029. },
  2030. isFile(mode) {
  2031. return (mode & 61440) === 32768;
  2032. },
  2033. isDir(mode) {
  2034. return (mode & 61440) === 16384;
  2035. },
  2036. isLink(mode) {
  2037. return (mode & 61440) === 40960;
  2038. },
  2039. isChrdev(mode) {
  2040. return (mode & 61440) === 8192;
  2041. },
  2042. isBlkdev(mode) {
  2043. return (mode & 61440) === 24576;
  2044. },
  2045. isFIFO(mode) {
  2046. return (mode & 61440) === 4096;
  2047. },
  2048. isSocket(mode) {
  2049. return (mode & 49152) === 49152;
  2050. },
  2051. flagsToPermissionString(flag) {
  2052. var perms = ['r', 'w', 'rw'][flag & 3];
  2053. if ((flag & 512)) {
  2054. perms += 'w';
  2055. }
  2056. return perms;
  2057. },
  2058. nodePermissions(node, perms) {
  2059. if (FS.ignorePermissions) {
  2060. return 0;
  2061. }
  2062. // return 0 if any user, group or owner bits are set.
  2063. if (perms.includes('r') && !(node.mode & 292)) {
  2064. return 2;
  2065. } else if (perms.includes('w') && !(node.mode & 146)) {
  2066. return 2;
  2067. } else if (perms.includes('x') && !(node.mode & 73)) {
  2068. return 2;
  2069. }
  2070. return 0;
  2071. },
  2072. mayLookup(dir) {
  2073. if (!FS.isDir(dir.mode)) return 54;
  2074. var errCode = FS.nodePermissions(dir, 'x');
  2075. if (errCode) return errCode;
  2076. if (!dir.node_ops.lookup) return 2;
  2077. return 0;
  2078. },
  2079. mayCreate(dir, name) {
  2080. if (!FS.isDir(dir.mode)) {
  2081. return 54;
  2082. }
  2083. try {
  2084. var node = FS.lookupNode(dir, name);
  2085. return 20;
  2086. } catch (e) {
  2087. }
  2088. return FS.nodePermissions(dir, 'wx');
  2089. },
  2090. mayDelete(dir, name, isdir) {
  2091. var node;
  2092. try {
  2093. node = FS.lookupNode(dir, name);
  2094. } catch (e) {
  2095. return e.errno;
  2096. }
  2097. var errCode = FS.nodePermissions(dir, 'wx');
  2098. if (errCode) {
  2099. return errCode;
  2100. }
  2101. if (isdir) {
  2102. if (!FS.isDir(node.mode)) {
  2103. return 54;
  2104. }
  2105. if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
  2106. return 10;
  2107. }
  2108. } else {
  2109. if (FS.isDir(node.mode)) {
  2110. return 31;
  2111. }
  2112. }
  2113. return 0;
  2114. },
  2115. mayOpen(node, flags) {
  2116. if (!node) {
  2117. return 44;
  2118. }
  2119. if (FS.isLink(node.mode)) {
  2120. return 32;
  2121. } else if (FS.isDir(node.mode)) {
  2122. if (FS.flagsToPermissionString(flags) !== 'r' // opening for write
  2123. || (flags & (512 | 64))) { // TODO: check for O_SEARCH? (== search for dir only)
  2124. return 31;
  2125. }
  2126. }
  2127. return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
  2128. },
  2129. checkOpExists(op, err) {
  2130. if (!op) {
  2131. throw new FS.ErrnoError(err);
  2132. }
  2133. return op;
  2134. },
  2135. MAX_OPEN_FDS:4096,
  2136. nextfd() {
  2137. for (var fd = 0; fd <= FS.MAX_OPEN_FDS; fd++) {
  2138. if (!FS.streams[fd]) {
  2139. return fd;
  2140. }
  2141. }
  2142. throw new FS.ErrnoError(33);
  2143. },
  2144. getStreamChecked(fd) {
  2145. var stream = FS.getStream(fd);
  2146. if (!stream) {
  2147. throw new FS.ErrnoError(8);
  2148. }
  2149. return stream;
  2150. },
  2151. getStream:(fd) => FS.streams[fd],
  2152. createStream(stream, fd = -1) {
  2153. assert(fd >= -1);
  2154. // clone it, so we can return an instance of FSStream
  2155. stream = Object.assign(new FS.FSStream(), stream);
  2156. if (fd == -1) {
  2157. fd = FS.nextfd();
  2158. }
  2159. stream.fd = fd;
  2160. FS.streams[fd] = stream;
  2161. return stream;
  2162. },
  2163. closeStream(fd) {
  2164. FS.streams[fd] = null;
  2165. },
  2166. dupStream(origStream, fd = -1) {
  2167. var stream = FS.createStream(origStream, fd);
  2168. stream.stream_ops?.dup?.(stream);
  2169. return stream;
  2170. },
  2171. doSetAttr(stream, node, attr) {
  2172. var setattr = stream?.stream_ops.setattr;
  2173. var arg = setattr ? stream : node;
  2174. setattr ??= node.node_ops.setattr;
  2175. FS.checkOpExists(setattr, 63)
  2176. setattr(arg, attr);
  2177. },
  2178. chrdev_stream_ops:{
  2179. open(stream) {
  2180. var device = FS.getDevice(stream.node.rdev);
  2181. // override node's stream ops with the device's
  2182. stream.stream_ops = device.stream_ops;
  2183. // forward the open call
  2184. stream.stream_ops.open?.(stream);
  2185. },
  2186. llseek() {
  2187. throw new FS.ErrnoError(70);
  2188. },
  2189. },
  2190. major:(dev) => ((dev) >> 8),
  2191. minor:(dev) => ((dev) & 0xff),
  2192. makedev:(ma, mi) => ((ma) << 8 | (mi)),
  2193. registerDevice(dev, ops) {
  2194. FS.devices[dev] = { stream_ops: ops };
  2195. },
  2196. getDevice:(dev) => FS.devices[dev],
  2197. getMounts(mount) {
  2198. var mounts = [];
  2199. var check = [mount];
  2200. while (check.length) {
  2201. var m = check.pop();
  2202. mounts.push(m);
  2203. check.push(...m.mounts);
  2204. }
  2205. return mounts;
  2206. },
  2207. syncfs(populate, callback) {
  2208. if (typeof populate == 'function') {
  2209. callback = populate;
  2210. populate = false;
  2211. }
  2212. FS.syncFSRequests++;
  2213. if (FS.syncFSRequests > 1) {
  2214. err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`);
  2215. }
  2216. var mounts = FS.getMounts(FS.root.mount);
  2217. var completed = 0;
  2218. function doCallback(errCode) {
  2219. assert(FS.syncFSRequests > 0);
  2220. FS.syncFSRequests--;
  2221. return callback(errCode);
  2222. }
  2223. function done(errCode) {
  2224. if (errCode) {
  2225. if (!done.errored) {
  2226. done.errored = true;
  2227. return doCallback(errCode);
  2228. }
  2229. return;
  2230. }
  2231. if (++completed >= mounts.length) {
  2232. doCallback(null);
  2233. }
  2234. };
  2235. // sync all mounts
  2236. mounts.forEach((mount) => {
  2237. if (!mount.type.syncfs) {
  2238. return done(null);
  2239. }
  2240. mount.type.syncfs(mount, populate, done);
  2241. });
  2242. },
  2243. mount(type, opts, mountpoint) {
  2244. if (typeof type == 'string') {
  2245. // The filesystem was not included, and instead we have an error
  2246. // message stored in the variable.
  2247. throw type;
  2248. }
  2249. var root = mountpoint === '/';
  2250. var pseudo = !mountpoint;
  2251. var node;
  2252. if (root && FS.root) {
  2253. throw new FS.ErrnoError(10);
  2254. } else if (!root && !pseudo) {
  2255. var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
  2256. mountpoint = lookup.path; // use the absolute path
  2257. node = lookup.node;
  2258. if (FS.isMountpoint(node)) {
  2259. throw new FS.ErrnoError(10);
  2260. }
  2261. if (!FS.isDir(node.mode)) {
  2262. throw new FS.ErrnoError(54);
  2263. }
  2264. }
  2265. var mount = {
  2266. type,
  2267. opts,
  2268. mountpoint,
  2269. mounts: []
  2270. };
  2271. // create a root node for the fs
  2272. var mountRoot = type.mount(mount);
  2273. mountRoot.mount = mount;
  2274. mount.root = mountRoot;
  2275. if (root) {
  2276. FS.root = mountRoot;
  2277. } else if (node) {
  2278. // set as a mountpoint
  2279. node.mounted = mount;
  2280. // add the new mount to the current mount's children
  2281. if (node.mount) {
  2282. node.mount.mounts.push(mount);
  2283. }
  2284. }
  2285. return mountRoot;
  2286. },
  2287. unmount(mountpoint) {
  2288. var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
  2289. if (!FS.isMountpoint(lookup.node)) {
  2290. throw new FS.ErrnoError(28);
  2291. }
  2292. // destroy the nodes for this mount, and all its child mounts
  2293. var node = lookup.node;
  2294. var mount = node.mounted;
  2295. var mounts = FS.getMounts(mount);
  2296. Object.keys(FS.nameTable).forEach((hash) => {
  2297. var current = FS.nameTable[hash];
  2298. while (current) {
  2299. var next = current.name_next;
  2300. if (mounts.includes(current.mount)) {
  2301. FS.destroyNode(current);
  2302. }
  2303. current = next;
  2304. }
  2305. });
  2306. // no longer a mountpoint
  2307. node.mounted = null;
  2308. // remove this mount from the child mounts
  2309. var idx = node.mount.mounts.indexOf(mount);
  2310. assert(idx !== -1);
  2311. node.mount.mounts.splice(idx, 1);
  2312. },
  2313. lookup(parent, name) {
  2314. return parent.node_ops.lookup(parent, name);
  2315. },
  2316. mknod(path, mode, dev) {
  2317. var lookup = FS.lookupPath(path, { parent: true });
  2318. var parent = lookup.node;
  2319. var name = PATH.basename(path);
  2320. if (!name) {
  2321. throw new FS.ErrnoError(28);
  2322. }
  2323. if (name === '.' || name === '..') {
  2324. throw new FS.ErrnoError(20);
  2325. }
  2326. var errCode = FS.mayCreate(parent, name);
  2327. if (errCode) {
  2328. throw new FS.ErrnoError(errCode);
  2329. }
  2330. if (!parent.node_ops.mknod) {
  2331. throw new FS.ErrnoError(63);
  2332. }
  2333. return parent.node_ops.mknod(parent, name, mode, dev);
  2334. },
  2335. statfs(path) {
  2336. return FS.statfsNode(FS.lookupPath(path, {follow: true}).node);
  2337. },
  2338. statfsStream(stream) {
  2339. // We keep a separate statfsStream function because noderawfs overrides
  2340. // it. In noderawfs, stream.node is sometimes null. Instead, we need to
  2341. // look at stream.path.
  2342. return FS.statfsNode(stream.node);
  2343. },
  2344. statfsNode(node) {
  2345. // NOTE: None of the defaults here are true. We're just returning safe and
  2346. // sane values. Currently nodefs and rawfs replace these defaults,
  2347. // other file systems leave them alone.
  2348. var rtn = {
  2349. bsize: 4096,
  2350. frsize: 4096,
  2351. blocks: 1e6,
  2352. bfree: 5e5,
  2353. bavail: 5e5,
  2354. files: FS.nextInode,
  2355. ffree: FS.nextInode - 1,
  2356. fsid: 42,
  2357. flags: 2,
  2358. namelen: 255,
  2359. };
  2360. if (node.node_ops.statfs) {
  2361. Object.assign(rtn, node.node_ops.statfs(node.mount.opts.root));
  2362. }
  2363. return rtn;
  2364. },
  2365. create(path, mode = 0o666) {
  2366. mode &= 4095;
  2367. mode |= 32768;
  2368. return FS.mknod(path, mode, 0);
  2369. },
  2370. mkdir(path, mode = 0o777) {
  2371. mode &= 511 | 512;
  2372. mode |= 16384;
  2373. return FS.mknod(path, mode, 0);
  2374. },
  2375. mkdirTree(path, mode) {
  2376. var dirs = path.split('/');
  2377. var d = '';
  2378. for (var i = 0; i < dirs.length; ++i) {
  2379. if (!dirs[i]) continue;
  2380. d += '/' + dirs[i];
  2381. try {
  2382. FS.mkdir(d, mode);
  2383. } catch(e) {
  2384. if (e.errno != 20) throw e;
  2385. }
  2386. }
  2387. },
  2388. mkdev(path, mode, dev) {
  2389. if (typeof dev == 'undefined') {
  2390. dev = mode;
  2391. mode = 0o666;
  2392. }
  2393. mode |= 8192;
  2394. return FS.mknod(path, mode, dev);
  2395. },
  2396. symlink(oldpath, newpath) {
  2397. if (!PATH_FS.resolve(oldpath)) {
  2398. throw new FS.ErrnoError(44);
  2399. }
  2400. var lookup = FS.lookupPath(newpath, { parent: true });
  2401. var parent = lookup.node;
  2402. if (!parent) {
  2403. throw new FS.ErrnoError(44);
  2404. }
  2405. var newname = PATH.basename(newpath);
  2406. var errCode = FS.mayCreate(parent, newname);
  2407. if (errCode) {
  2408. throw new FS.ErrnoError(errCode);
  2409. }
  2410. if (!parent.node_ops.symlink) {
  2411. throw new FS.ErrnoError(63);
  2412. }
  2413. return parent.node_ops.symlink(parent, newname, oldpath);
  2414. },
  2415. rename(old_path, new_path) {
  2416. var old_dirname = PATH.dirname(old_path);
  2417. var new_dirname = PATH.dirname(new_path);
  2418. var old_name = PATH.basename(old_path);
  2419. var new_name = PATH.basename(new_path);
  2420. // parents must exist
  2421. var lookup, old_dir, new_dir;
  2422. // let the errors from non existent directories percolate up
  2423. lookup = FS.lookupPath(old_path, { parent: true });
  2424. old_dir = lookup.node;
  2425. lookup = FS.lookupPath(new_path, { parent: true });
  2426. new_dir = lookup.node;
  2427. if (!old_dir || !new_dir) throw new FS.ErrnoError(44);
  2428. // need to be part of the same mount
  2429. if (old_dir.mount !== new_dir.mount) {
  2430. throw new FS.ErrnoError(75);
  2431. }
  2432. // source must exist
  2433. var old_node = FS.lookupNode(old_dir, old_name);
  2434. // old path should not be an ancestor of the new path
  2435. var relative = PATH_FS.relative(old_path, new_dirname);
  2436. if (relative.charAt(0) !== '.') {
  2437. throw new FS.ErrnoError(28);
  2438. }
  2439. // new path should not be an ancestor of the old path
  2440. relative = PATH_FS.relative(new_path, old_dirname);
  2441. if (relative.charAt(0) !== '.') {
  2442. throw new FS.ErrnoError(55);
  2443. }
  2444. // see if the new path already exists
  2445. var new_node;
  2446. try {
  2447. new_node = FS.lookupNode(new_dir, new_name);
  2448. } catch (e) {
  2449. // not fatal
  2450. }
  2451. // early out if nothing needs to change
  2452. if (old_node === new_node) {
  2453. return;
  2454. }
  2455. // we'll need to delete the old entry
  2456. var isdir = FS.isDir(old_node.mode);
  2457. var errCode = FS.mayDelete(old_dir, old_name, isdir);
  2458. if (errCode) {
  2459. throw new FS.ErrnoError(errCode);
  2460. }
  2461. // need delete permissions if we'll be overwriting.
  2462. // need create permissions if new doesn't already exist.
  2463. errCode = new_node ?
  2464. FS.mayDelete(new_dir, new_name, isdir) :
  2465. FS.mayCreate(new_dir, new_name);
  2466. if (errCode) {
  2467. throw new FS.ErrnoError(errCode);
  2468. }
  2469. if (!old_dir.node_ops.rename) {
  2470. throw new FS.ErrnoError(63);
  2471. }
  2472. if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) {
  2473. throw new FS.ErrnoError(10);
  2474. }
  2475. // if we are going to change the parent, check write permissions
  2476. if (new_dir !== old_dir) {
  2477. errCode = FS.nodePermissions(old_dir, 'w');
  2478. if (errCode) {
  2479. throw new FS.ErrnoError(errCode);
  2480. }
  2481. }
  2482. // remove the node from the lookup hash
  2483. FS.hashRemoveNode(old_node);
  2484. // do the underlying fs rename
  2485. try {
  2486. old_dir.node_ops.rename(old_node, new_dir, new_name);
  2487. // update old node (we do this here to avoid each backend
  2488. // needing to)
  2489. old_node.parent = new_dir;
  2490. } catch (e) {
  2491. throw e;
  2492. } finally {
  2493. // add the node back to the hash (in case node_ops.rename
  2494. // changed its name)
  2495. FS.hashAddNode(old_node);
  2496. }
  2497. },
  2498. rmdir(path) {
  2499. var lookup = FS.lookupPath(path, { parent: true });
  2500. var parent = lookup.node;
  2501. var name = PATH.basename(path);
  2502. var node = FS.lookupNode(parent, name);
  2503. var errCode = FS.mayDelete(parent, name, true);
  2504. if (errCode) {
  2505. throw new FS.ErrnoError(errCode);
  2506. }
  2507. if (!parent.node_ops.rmdir) {
  2508. throw new FS.ErrnoError(63);
  2509. }
  2510. if (FS.isMountpoint(node)) {
  2511. throw new FS.ErrnoError(10);
  2512. }
  2513. parent.node_ops.rmdir(parent, name);
  2514. FS.destroyNode(node);
  2515. },
  2516. readdir(path) {
  2517. var lookup = FS.lookupPath(path, { follow: true });
  2518. var node = lookup.node;
  2519. var readdir = FS.checkOpExists(node.node_ops.readdir, 54);
  2520. return readdir(node);
  2521. },
  2522. unlink(path) {
  2523. var lookup = FS.lookupPath(path, { parent: true });
  2524. var parent = lookup.node;
  2525. if (!parent) {
  2526. throw new FS.ErrnoError(44);
  2527. }
  2528. var name = PATH.basename(path);
  2529. var node = FS.lookupNode(parent, name);
  2530. var errCode = FS.mayDelete(parent, name, false);
  2531. if (errCode) {
  2532. // According to POSIX, we should map EISDIR to EPERM, but
  2533. // we instead do what Linux does (and we must, as we use
  2534. // the musl linux libc).
  2535. throw new FS.ErrnoError(errCode);
  2536. }
  2537. if (!parent.node_ops.unlink) {
  2538. throw new FS.ErrnoError(63);
  2539. }
  2540. if (FS.isMountpoint(node)) {
  2541. throw new FS.ErrnoError(10);
  2542. }
  2543. parent.node_ops.unlink(parent, name);
  2544. FS.destroyNode(node);
  2545. },
  2546. readlink(path) {
  2547. var lookup = FS.lookupPath(path);
  2548. var link = lookup.node;
  2549. if (!link) {
  2550. throw new FS.ErrnoError(44);
  2551. }
  2552. if (!link.node_ops.readlink) {
  2553. throw new FS.ErrnoError(28);
  2554. }
  2555. return link.node_ops.readlink(link);
  2556. },
  2557. stat(path, dontFollow) {
  2558. var lookup = FS.lookupPath(path, { follow: !dontFollow });
  2559. var node = lookup.node;
  2560. var getattr = FS.checkOpExists(node.node_ops.getattr, 63);
  2561. return getattr(node);
  2562. },
  2563. fstat(fd) {
  2564. var stream = FS.getStreamChecked(fd);
  2565. var node = stream.node;
  2566. var getattr = stream.stream_ops.getattr;
  2567. var arg = getattr ? stream : node;
  2568. getattr ??= node.node_ops.getattr;
  2569. FS.checkOpExists(getattr, 63)
  2570. return getattr(arg);
  2571. },
  2572. lstat(path) {
  2573. return FS.stat(path, true);
  2574. },
  2575. doChmod(stream, node, mode, dontFollow) {
  2576. FS.doSetAttr(stream, node, {
  2577. mode: (mode & 4095) | (node.mode & ~4095),
  2578. ctime: Date.now(),
  2579. dontFollow
  2580. });
  2581. },
  2582. chmod(path, mode, dontFollow) {
  2583. var node;
  2584. if (typeof path == 'string') {
  2585. var lookup = FS.lookupPath(path, { follow: !dontFollow });
  2586. node = lookup.node;
  2587. } else {
  2588. node = path;
  2589. }
  2590. FS.doChmod(null, node, mode, dontFollow);
  2591. },
  2592. lchmod(path, mode) {
  2593. FS.chmod(path, mode, true);
  2594. },
  2595. fchmod(fd, mode) {
  2596. var stream = FS.getStreamChecked(fd);
  2597. FS.doChmod(stream, stream.node, mode, false);
  2598. },
  2599. doChown(stream, node, dontFollow) {
  2600. FS.doSetAttr(stream, node, {
  2601. timestamp: Date.now(),
  2602. dontFollow
  2603. // we ignore the uid / gid for now
  2604. });
  2605. },
  2606. chown(path, uid, gid, dontFollow) {
  2607. var node;
  2608. if (typeof path == 'string') {
  2609. var lookup = FS.lookupPath(path, { follow: !dontFollow });
  2610. node = lookup.node;
  2611. } else {
  2612. node = path;
  2613. }
  2614. FS.doChown(null, node, dontFollow);
  2615. },
  2616. lchown(path, uid, gid) {
  2617. FS.chown(path, uid, gid, true);
  2618. },
  2619. fchown(fd, uid, gid) {
  2620. var stream = FS.getStreamChecked(fd);
  2621. FS.doChown(stream, stream.node, false);
  2622. },
  2623. doTruncate(stream, node, len) {
  2624. if (FS.isDir(node.mode)) {
  2625. throw new FS.ErrnoError(31);
  2626. }
  2627. if (!FS.isFile(node.mode)) {
  2628. throw new FS.ErrnoError(28);
  2629. }
  2630. var errCode = FS.nodePermissions(node, 'w');
  2631. if (errCode) {
  2632. throw new FS.ErrnoError(errCode);
  2633. }
  2634. FS.doSetAttr(stream, node, {
  2635. size: len,
  2636. timestamp: Date.now()
  2637. });
  2638. },
  2639. truncate(path, len) {
  2640. if (len < 0) {
  2641. throw new FS.ErrnoError(28);
  2642. }
  2643. var node;
  2644. if (typeof path == 'string') {
  2645. var lookup = FS.lookupPath(path, { follow: true });
  2646. node = lookup.node;
  2647. } else {
  2648. node = path;
  2649. }
  2650. FS.doTruncate(null, node, len);
  2651. },
  2652. ftruncate(fd, len) {
  2653. var stream = FS.getStreamChecked(fd);
  2654. if (len < 0 || (stream.flags & 2097155) === 0) {
  2655. throw new FS.ErrnoError(28);
  2656. }
  2657. FS.doTruncate(stream, stream.node, len);
  2658. },
  2659. utime(path, atime, mtime) {
  2660. var lookup = FS.lookupPath(path, { follow: true });
  2661. var node = lookup.node;
  2662. var setattr = FS.checkOpExists(node.node_ops.setattr, 63);
  2663. setattr(node, {
  2664. atime: atime,
  2665. mtime: mtime
  2666. });
  2667. },
  2668. open(path, flags, mode = 0o666) {
  2669. if (path === "") {
  2670. throw new FS.ErrnoError(44);
  2671. }
  2672. flags = typeof flags == 'string' ? FS_modeStringToFlags(flags) : flags;
  2673. if ((flags & 64)) {
  2674. mode = (mode & 4095) | 32768;
  2675. } else {
  2676. mode = 0;
  2677. }
  2678. var node;
  2679. var isDirPath;
  2680. if (typeof path == 'object') {
  2681. node = path;
  2682. } else {
  2683. isDirPath = path.endsWith("/");
  2684. // noent_okay makes it so that if the final component of the path
  2685. // doesn't exist, lookupPath returns `node: undefined`. `path` will be
  2686. // updated to point to the target of all symlinks.
  2687. var lookup = FS.lookupPath(path, {
  2688. follow: !(flags & 131072),
  2689. noent_okay: true
  2690. });
  2691. node = lookup.node;
  2692. path = lookup.path;
  2693. }
  2694. // perhaps we need to create the node
  2695. var created = false;
  2696. if ((flags & 64)) {
  2697. if (node) {
  2698. // if O_CREAT and O_EXCL are set, error out if the node already exists
  2699. if ((flags & 128)) {
  2700. throw new FS.ErrnoError(20);
  2701. }
  2702. } else if (isDirPath) {
  2703. throw new FS.ErrnoError(31);
  2704. } else {
  2705. // node doesn't exist, try to create it
  2706. // Ignore the permission bits here to ensure we can `open` this new
  2707. // file below. We use chmod below the apply the permissions once the
  2708. // file is open.
  2709. node = FS.mknod(path, mode | 0o777, 0);
  2710. created = true;
  2711. }
  2712. }
  2713. if (!node) {
  2714. throw new FS.ErrnoError(44);
  2715. }
  2716. // can't truncate a device
  2717. if (FS.isChrdev(node.mode)) {
  2718. flags &= ~512;
  2719. }
  2720. // if asked only for a directory, then this must be one
  2721. if ((flags & 65536) && !FS.isDir(node.mode)) {
  2722. throw new FS.ErrnoError(54);
  2723. }
  2724. // check permissions, if this is not a file we just created now (it is ok to
  2725. // create and write to a file with read-only permissions; it is read-only
  2726. // for later use)
  2727. if (!created) {
  2728. var errCode = FS.mayOpen(node, flags);
  2729. if (errCode) {
  2730. throw new FS.ErrnoError(errCode);
  2731. }
  2732. }
  2733. // do truncation if necessary
  2734. if ((flags & 512) && !created) {
  2735. FS.truncate(node, 0);
  2736. }
  2737. // we've already handled these, don't pass down to the underlying vfs
  2738. flags &= ~(128 | 512 | 131072);
  2739. // register the stream with the filesystem
  2740. var stream = FS.createStream({
  2741. node,
  2742. path: FS.getPath(node), // we want the absolute path to the node
  2743. flags,
  2744. seekable: true,
  2745. position: 0,
  2746. stream_ops: node.stream_ops,
  2747. // used by the file family libc calls (fopen, fwrite, ferror, etc.)
  2748. ungotten: [],
  2749. error: false
  2750. });
  2751. // call the new stream's open function
  2752. if (stream.stream_ops.open) {
  2753. stream.stream_ops.open(stream);
  2754. }
  2755. if (created) {
  2756. FS.chmod(node, mode & 0o777);
  2757. }
  2758. if (Module['logReadFiles'] && !(flags & 1)) {
  2759. if (!(path in FS.readFiles)) {
  2760. FS.readFiles[path] = 1;
  2761. }
  2762. }
  2763. return stream;
  2764. },
  2765. close(stream) {
  2766. if (FS.isClosed(stream)) {
  2767. throw new FS.ErrnoError(8);
  2768. }
  2769. if (stream.getdents) stream.getdents = null; // free readdir state
  2770. try {
  2771. if (stream.stream_ops.close) {
  2772. stream.stream_ops.close(stream);
  2773. }
  2774. } catch (e) {
  2775. throw e;
  2776. } finally {
  2777. FS.closeStream(stream.fd);
  2778. }
  2779. stream.fd = null;
  2780. },
  2781. isClosed(stream) {
  2782. return stream.fd === null;
  2783. },
  2784. llseek(stream, offset, whence) {
  2785. if (FS.isClosed(stream)) {
  2786. throw new FS.ErrnoError(8);
  2787. }
  2788. if (!stream.seekable || !stream.stream_ops.llseek) {
  2789. throw new FS.ErrnoError(70);
  2790. }
  2791. if (whence != 0 && whence != 1 && whence != 2) {
  2792. throw new FS.ErrnoError(28);
  2793. }
  2794. stream.position = stream.stream_ops.llseek(stream, offset, whence);
  2795. stream.ungotten = [];
  2796. return stream.position;
  2797. },
  2798. read(stream, buffer, offset, length, position) {
  2799. assert(offset >= 0);
  2800. if (length < 0 || position < 0) {
  2801. throw new FS.ErrnoError(28);
  2802. }
  2803. if (FS.isClosed(stream)) {
  2804. throw new FS.ErrnoError(8);
  2805. }
  2806. if ((stream.flags & 2097155) === 1) {
  2807. throw new FS.ErrnoError(8);
  2808. }
  2809. if (FS.isDir(stream.node.mode)) {
  2810. throw new FS.ErrnoError(31);
  2811. }
  2812. if (!stream.stream_ops.read) {
  2813. throw new FS.ErrnoError(28);
  2814. }
  2815. var seeking = typeof position != 'undefined';
  2816. if (!seeking) {
  2817. position = stream.position;
  2818. } else if (!stream.seekable) {
  2819. throw new FS.ErrnoError(70);
  2820. }
  2821. var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position);
  2822. if (!seeking) stream.position += bytesRead;
  2823. return bytesRead;
  2824. },
  2825. write(stream, buffer, offset, length, position, canOwn) {
  2826. assert(offset >= 0);
  2827. if (length < 0 || position < 0) {
  2828. throw new FS.ErrnoError(28);
  2829. }
  2830. if (FS.isClosed(stream)) {
  2831. throw new FS.ErrnoError(8);
  2832. }
  2833. if ((stream.flags & 2097155) === 0) {
  2834. throw new FS.ErrnoError(8);
  2835. }
  2836. if (FS.isDir(stream.node.mode)) {
  2837. throw new FS.ErrnoError(31);
  2838. }
  2839. if (!stream.stream_ops.write) {
  2840. throw new FS.ErrnoError(28);
  2841. }
  2842. if (stream.seekable && stream.flags & 1024) {
  2843. // seek to the end before writing in append mode
  2844. FS.llseek(stream, 0, 2);
  2845. }
  2846. var seeking = typeof position != 'undefined';
  2847. if (!seeking) {
  2848. position = stream.position;
  2849. } else if (!stream.seekable) {
  2850. throw new FS.ErrnoError(70);
  2851. }
  2852. var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
  2853. if (!seeking) stream.position += bytesWritten;
  2854. return bytesWritten;
  2855. },
  2856. allocate(stream, offset, length) {
  2857. if (FS.isClosed(stream)) {
  2858. throw new FS.ErrnoError(8);
  2859. }
  2860. if (offset < 0 || length <= 0) {
  2861. throw new FS.ErrnoError(28);
  2862. }
  2863. if ((stream.flags & 2097155) === 0) {
  2864. throw new FS.ErrnoError(8);
  2865. }
  2866. if (!FS.isFile(stream.node.mode) && !FS.isDir(stream.node.mode)) {
  2867. throw new FS.ErrnoError(43);
  2868. }
  2869. if (!stream.stream_ops.allocate) {
  2870. throw new FS.ErrnoError(138);
  2871. }
  2872. stream.stream_ops.allocate(stream, offset, length);
  2873. },
  2874. mmap(stream, length, position, prot, flags) {
  2875. // User requests writing to file (prot & PROT_WRITE != 0).
  2876. // Checking if we have permissions to write to the file unless
  2877. // MAP_PRIVATE flag is set. According to POSIX spec it is possible
  2878. // to write to file opened in read-only mode with MAP_PRIVATE flag,
  2879. // as all modifications will be visible only in the memory of
  2880. // the current process.
  2881. if ((prot & 2) !== 0
  2882. && (flags & 2) === 0
  2883. && (stream.flags & 2097155) !== 2) {
  2884. throw new FS.ErrnoError(2);
  2885. }
  2886. if ((stream.flags & 2097155) === 1) {
  2887. throw new FS.ErrnoError(2);
  2888. }
  2889. if (!stream.stream_ops.mmap) {
  2890. throw new FS.ErrnoError(43);
  2891. }
  2892. if (!length) {
  2893. throw new FS.ErrnoError(28);
  2894. }
  2895. return stream.stream_ops.mmap(stream, length, position, prot, flags);
  2896. },
  2897. msync(stream, buffer, offset, length, mmapFlags) {
  2898. assert(offset >= 0);
  2899. if (!stream.stream_ops.msync) {
  2900. return 0;
  2901. }
  2902. return stream.stream_ops.msync(stream, buffer, offset, length, mmapFlags);
  2903. },
  2904. ioctl(stream, cmd, arg) {
  2905. if (!stream.stream_ops.ioctl) {
  2906. throw new FS.ErrnoError(59);
  2907. }
  2908. return stream.stream_ops.ioctl(stream, cmd, arg);
  2909. },
  2910. readFile(path, opts = {}) {
  2911. opts.flags = opts.flags || 0;
  2912. opts.encoding = opts.encoding || 'binary';
  2913. if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
  2914. throw new Error(`Invalid encoding type "${opts.encoding}"`);
  2915. }
  2916. var ret;
  2917. var stream = FS.open(path, opts.flags);
  2918. var stat = FS.stat(path);
  2919. var length = stat.size;
  2920. var buf = new Uint8Array(length);
  2921. FS.read(stream, buf, 0, length, 0);
  2922. if (opts.encoding === 'utf8') {
  2923. ret = UTF8ArrayToString(buf);
  2924. } else if (opts.encoding === 'binary') {
  2925. ret = buf;
  2926. }
  2927. FS.close(stream);
  2928. return ret;
  2929. },
  2930. writeFile(path, data, opts = {}) {
  2931. opts.flags = opts.flags || 577;
  2932. var stream = FS.open(path, opts.flags, opts.mode);
  2933. if (typeof data == 'string') {
  2934. var buf = new Uint8Array(lengthBytesUTF8(data)+1);
  2935. var actualNumBytes = stringToUTF8Array(data, buf, 0, buf.length);
  2936. FS.write(stream, buf, 0, actualNumBytes, undefined, opts.canOwn);
  2937. } else if (ArrayBuffer.isView(data)) {
  2938. FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn);
  2939. } else {
  2940. throw new Error('Unsupported data type');
  2941. }
  2942. FS.close(stream);
  2943. },
  2944. cwd:() => FS.currentPath,
  2945. chdir(path) {
  2946. var lookup = FS.lookupPath(path, { follow: true });
  2947. if (lookup.node === null) {
  2948. throw new FS.ErrnoError(44);
  2949. }
  2950. if (!FS.isDir(lookup.node.mode)) {
  2951. throw new FS.ErrnoError(54);
  2952. }
  2953. var errCode = FS.nodePermissions(lookup.node, 'x');
  2954. if (errCode) {
  2955. throw new FS.ErrnoError(errCode);
  2956. }
  2957. FS.currentPath = lookup.path;
  2958. },
  2959. createDefaultDirectories() {
  2960. FS.mkdir('/tmp');
  2961. FS.mkdir('/home');
  2962. FS.mkdir('/home/web_user');
  2963. },
  2964. createDefaultDevices() {
  2965. // create /dev
  2966. FS.mkdir('/dev');
  2967. // setup /dev/null
  2968. FS.registerDevice(FS.makedev(1, 3), {
  2969. read: () => 0,
  2970. write: (stream, buffer, offset, length, pos) => length,
  2971. llseek: () => 0,
  2972. });
  2973. FS.mkdev('/dev/null', FS.makedev(1, 3));
  2974. // setup /dev/tty and /dev/tty1
  2975. // stderr needs to print output using err() rather than out()
  2976. // so we register a second tty just for it.
  2977. TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
  2978. TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
  2979. FS.mkdev('/dev/tty', FS.makedev(5, 0));
  2980. FS.mkdev('/dev/tty1', FS.makedev(6, 0));
  2981. // setup /dev/[u]random
  2982. // use a buffer to avoid overhead of individual crypto calls per byte
  2983. var randomBuffer = new Uint8Array(1024), randomLeft = 0;
  2984. var randomByte = () => {
  2985. if (randomLeft === 0) {
  2986. randomFill(randomBuffer);
  2987. randomLeft = randomBuffer.byteLength;
  2988. }
  2989. return randomBuffer[--randomLeft];
  2990. };
  2991. FS.createDevice('/dev', 'random', randomByte);
  2992. FS.createDevice('/dev', 'urandom', randomByte);
  2993. // we're not going to emulate the actual shm device,
  2994. // just create the tmp dirs that reside in it commonly
  2995. FS.mkdir('/dev/shm');
  2996. FS.mkdir('/dev/shm/tmp');
  2997. },
  2998. createSpecialDirectories() {
  2999. // create /proc/self/fd which allows /proc/self/fd/6 => readlink gives the
  3000. // name of the stream for fd 6 (see test_unistd_ttyname)
  3001. FS.mkdir('/proc');
  3002. var proc_self = FS.mkdir('/proc/self');
  3003. FS.mkdir('/proc/self/fd');
  3004. FS.mount({
  3005. mount() {
  3006. var node = FS.createNode(proc_self, 'fd', 16895, 73);
  3007. node.stream_ops = {
  3008. llseek: MEMFS.stream_ops.llseek,
  3009. };
  3010. node.node_ops = {
  3011. lookup(parent, name) {
  3012. var fd = +name;
  3013. var stream = FS.getStreamChecked(fd);
  3014. var ret = {
  3015. parent: null,
  3016. mount: { mountpoint: 'fake' },
  3017. node_ops: { readlink: () => stream.path },
  3018. id: fd + 1,
  3019. };
  3020. ret.parent = ret; // make it look like a simple root node
  3021. return ret;
  3022. },
  3023. readdir() {
  3024. return Array.from(FS.streams.entries())
  3025. .filter(([k, v]) => v)
  3026. .map(([k, v]) => k.toString());
  3027. }
  3028. };
  3029. return node;
  3030. }
  3031. }, {}, '/proc/self/fd');
  3032. },
  3033. createStandardStreams(input, output, error) {
  3034. // TODO deprecate the old functionality of a single
  3035. // input / output callback and that utilizes FS.createDevice
  3036. // and instead require a unique set of stream ops
  3037. // by default, we symlink the standard streams to the
  3038. // default tty devices. however, if the standard streams
  3039. // have been overwritten we create a unique device for
  3040. // them instead.
  3041. if (input) {
  3042. FS.createDevice('/dev', 'stdin', input);
  3043. } else {
  3044. FS.symlink('/dev/tty', '/dev/stdin');
  3045. }
  3046. if (output) {
  3047. FS.createDevice('/dev', 'stdout', null, output);
  3048. } else {
  3049. FS.symlink('/dev/tty', '/dev/stdout');
  3050. }
  3051. if (error) {
  3052. FS.createDevice('/dev', 'stderr', null, error);
  3053. } else {
  3054. FS.symlink('/dev/tty1', '/dev/stderr');
  3055. }
  3056. // open default streams for the stdin, stdout and stderr devices
  3057. var stdin = FS.open('/dev/stdin', 0);
  3058. var stdout = FS.open('/dev/stdout', 1);
  3059. var stderr = FS.open('/dev/stderr', 1);
  3060. assert(stdin.fd === 0, `invalid handle for stdin (${stdin.fd})`);
  3061. assert(stdout.fd === 1, `invalid handle for stdout (${stdout.fd})`);
  3062. assert(stderr.fd === 2, `invalid handle for stderr (${stderr.fd})`);
  3063. },
  3064. staticInit() {
  3065. FS.nameTable = new Array(4096);
  3066. FS.mount(MEMFS, {}, '/');
  3067. FS.createDefaultDirectories();
  3068. FS.createDefaultDevices();
  3069. FS.createSpecialDirectories();
  3070. FS.filesystems = {
  3071. 'MEMFS': MEMFS,
  3072. };
  3073. },
  3074. init(input, output, error) {
  3075. 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)');
  3076. FS.initialized = true;
  3077. // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here
  3078. input ??= Module['stdin'];
  3079. output ??= Module['stdout'];
  3080. error ??= Module['stderr'];
  3081. FS.createStandardStreams(input, output, error);
  3082. },
  3083. quit() {
  3084. FS.initialized = false;
  3085. // force-flush all streams, so we get musl std streams printed out
  3086. _fflush(0);
  3087. // close all of our streams
  3088. for (var i = 0; i < FS.streams.length; i++) {
  3089. var stream = FS.streams[i];
  3090. if (!stream) {
  3091. continue;
  3092. }
  3093. FS.close(stream);
  3094. }
  3095. },
  3096. findObject(path, dontResolveLastLink) {
  3097. var ret = FS.analyzePath(path, dontResolveLastLink);
  3098. if (!ret.exists) {
  3099. return null;
  3100. }
  3101. return ret.object;
  3102. },
  3103. analyzePath(path, dontResolveLastLink) {
  3104. // operate from within the context of the symlink's target
  3105. try {
  3106. var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
  3107. path = lookup.path;
  3108. } catch (e) {
  3109. }
  3110. var ret = {
  3111. isRoot: false, exists: false, error: 0, name: null, path: null, object: null,
  3112. parentExists: false, parentPath: null, parentObject: null
  3113. };
  3114. try {
  3115. var lookup = FS.lookupPath(path, { parent: true });
  3116. ret.parentExists = true;
  3117. ret.parentPath = lookup.path;
  3118. ret.parentObject = lookup.node;
  3119. ret.name = PATH.basename(path);
  3120. lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
  3121. ret.exists = true;
  3122. ret.path = lookup.path;
  3123. ret.object = lookup.node;
  3124. ret.name = lookup.node.name;
  3125. ret.isRoot = lookup.path === '/';
  3126. } catch (e) {
  3127. ret.error = e.errno;
  3128. };
  3129. return ret;
  3130. },
  3131. createPath(parent, path, canRead, canWrite) {
  3132. parent = typeof parent == 'string' ? parent : FS.getPath(parent);
  3133. var parts = path.split('/').reverse();
  3134. while (parts.length) {
  3135. var part = parts.pop();
  3136. if (!part) continue;
  3137. var current = PATH.join2(parent, part);
  3138. try {
  3139. FS.mkdir(current);
  3140. } catch (e) {
  3141. // ignore EEXIST
  3142. }
  3143. parent = current;
  3144. }
  3145. return current;
  3146. },
  3147. createFile(parent, name, properties, canRead, canWrite) {
  3148. var path = PATH.join2(typeof parent == 'string' ? parent : FS.getPath(parent), name);
  3149. var mode = FS_getMode(canRead, canWrite);
  3150. return FS.create(path, mode);
  3151. },
  3152. createDataFile(parent, name, data, canRead, canWrite, canOwn) {
  3153. var path = name;
  3154. if (parent) {
  3155. parent = typeof parent == 'string' ? parent : FS.getPath(parent);
  3156. path = name ? PATH.join2(parent, name) : parent;
  3157. }
  3158. var mode = FS_getMode(canRead, canWrite);
  3159. var node = FS.create(path, mode);
  3160. if (data) {
  3161. if (typeof data == 'string') {
  3162. var arr = new Array(data.length);
  3163. for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
  3164. data = arr;
  3165. }
  3166. // make sure we can write to the file
  3167. FS.chmod(node, mode | 146);
  3168. var stream = FS.open(node, 577);
  3169. FS.write(stream, data, 0, data.length, 0, canOwn);
  3170. FS.close(stream);
  3171. FS.chmod(node, mode);
  3172. }
  3173. },
  3174. createDevice(parent, name, input, output) {
  3175. var path = PATH.join2(typeof parent == 'string' ? parent : FS.getPath(parent), name);
  3176. var mode = FS_getMode(!!input, !!output);
  3177. FS.createDevice.major ??= 64;
  3178. var dev = FS.makedev(FS.createDevice.major++, 0);
  3179. // Create a fake device that a set of stream ops to emulate
  3180. // the old behavior.
  3181. FS.registerDevice(dev, {
  3182. open(stream) {
  3183. stream.seekable = false;
  3184. },
  3185. close(stream) {
  3186. // flush any pending line data
  3187. if (output?.buffer?.length) {
  3188. output(10);
  3189. }
  3190. },
  3191. read(stream, buffer, offset, length, pos /* ignored */) {
  3192. var bytesRead = 0;
  3193. for (var i = 0; i < length; i++) {
  3194. var result;
  3195. try {
  3196. result = input();
  3197. } catch (e) {
  3198. throw new FS.ErrnoError(29);
  3199. }
  3200. if (result === undefined && bytesRead === 0) {
  3201. throw new FS.ErrnoError(6);
  3202. }
  3203. if (result === null || result === undefined) break;
  3204. bytesRead++;
  3205. buffer[offset+i] = result;
  3206. }
  3207. if (bytesRead) {
  3208. stream.node.atime = Date.now();
  3209. }
  3210. return bytesRead;
  3211. },
  3212. write(stream, buffer, offset, length, pos) {
  3213. for (var i = 0; i < length; i++) {
  3214. try {
  3215. output(buffer[offset+i]);
  3216. } catch (e) {
  3217. throw new FS.ErrnoError(29);
  3218. }
  3219. }
  3220. if (length) {
  3221. stream.node.mtime = stream.node.ctime = Date.now();
  3222. }
  3223. return i;
  3224. }
  3225. });
  3226. return FS.mkdev(path, mode, dev);
  3227. },
  3228. forceLoadFile(obj) {
  3229. if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
  3230. if (typeof XMLHttpRequest != 'undefined') {
  3231. 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.");
  3232. } else { // Command-line.
  3233. try {
  3234. obj.contents = readBinary(obj.url);
  3235. obj.usedBytes = obj.contents.length;
  3236. } catch (e) {
  3237. throw new FS.ErrnoError(29);
  3238. }
  3239. }
  3240. },
  3241. createLazyFile(parent, name, url, canRead, canWrite) {
  3242. // Lazy chunked Uint8Array (implements get and length from Uint8Array).
  3243. // Actual getting is abstracted away for eventual reuse.
  3244. class LazyUint8Array {
  3245. lengthKnown = false;
  3246. chunks = []; // Loaded chunks. Index is the chunk number
  3247. get(idx) {
  3248. if (idx > this.length-1 || idx < 0) {
  3249. return undefined;
  3250. }
  3251. var chunkOffset = idx % this.chunkSize;
  3252. var chunkNum = (idx / this.chunkSize)|0;
  3253. return this.getter(chunkNum)[chunkOffset];
  3254. }
  3255. setDataGetter(getter) {
  3256. this.getter = getter;
  3257. }
  3258. cacheLength() {
  3259. // Find length
  3260. var xhr = new XMLHttpRequest();
  3261. xhr.open('HEAD', url, false);
  3262. xhr.send(null);
  3263. if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
  3264. var datalength = Number(xhr.getResponseHeader("Content-length"));
  3265. var header;
  3266. var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";
  3267. var usesGzip = (header = xhr.getResponseHeader("Content-Encoding")) && header === "gzip";
  3268. var chunkSize = 1024*1024; // Chunk size in bytes
  3269. if (!hasByteServing) chunkSize = datalength;
  3270. // Function to get a range from the remote URL.
  3271. var doXHR = (from, to) => {
  3272. if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!");
  3273. if (to > datalength-1) throw new Error("only " + datalength + " bytes available! programmer error!");
  3274. // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
  3275. var xhr = new XMLHttpRequest();
  3276. xhr.open('GET', url, false);
  3277. if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);
  3278. // Some hints to the browser that we want binary data.
  3279. xhr.responseType = 'arraybuffer';
  3280. if (xhr.overrideMimeType) {
  3281. xhr.overrideMimeType('text/plain; charset=x-user-defined');
  3282. }
  3283. xhr.send(null);
  3284. if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
  3285. if (xhr.response !== undefined) {
  3286. return new Uint8Array(/** @type{Array<number>} */(xhr.response || []));
  3287. }
  3288. return intArrayFromString(xhr.responseText || '', true);
  3289. };
  3290. var lazyArray = this;
  3291. lazyArray.setDataGetter((chunkNum) => {
  3292. var start = chunkNum * chunkSize;
  3293. var end = (chunkNum+1) * chunkSize - 1; // including this byte
  3294. end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block
  3295. if (typeof lazyArray.chunks[chunkNum] == 'undefined') {
  3296. lazyArray.chunks[chunkNum] = doXHR(start, end);
  3297. }
  3298. if (typeof lazyArray.chunks[chunkNum] == 'undefined') throw new Error('doXHR failed!');
  3299. return lazyArray.chunks[chunkNum];
  3300. });
  3301. if (usesGzip || !datalength) {
  3302. // if the server uses gzip or doesn't supply the length, we have to download the whole file to get the (uncompressed) length
  3303. chunkSize = datalength = 1; // this will force getter(0)/doXHR do download the whole file
  3304. datalength = this.getter(0).length;
  3305. chunkSize = datalength;
  3306. out("LazyFiles on gzip forces download of the whole file when length is accessed");
  3307. }
  3308. this._length = datalength;
  3309. this._chunkSize = chunkSize;
  3310. this.lengthKnown = true;
  3311. }
  3312. get length() {
  3313. if (!this.lengthKnown) {
  3314. this.cacheLength();
  3315. }
  3316. return this._length;
  3317. }
  3318. get chunkSize() {
  3319. if (!this.lengthKnown) {
  3320. this.cacheLength();
  3321. }
  3322. return this._chunkSize;
  3323. }
  3324. }
  3325. if (typeof XMLHttpRequest != 'undefined') {
  3326. if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc';
  3327. var lazyArray = new LazyUint8Array();
  3328. var properties = { isDevice: false, contents: lazyArray };
  3329. } else {
  3330. var properties = { isDevice: false, url: url };
  3331. }
  3332. var node = FS.createFile(parent, name, properties, canRead, canWrite);
  3333. // This is a total hack, but I want to get this lazy file code out of the
  3334. // core of MEMFS. If we want to keep this lazy file concept I feel it should
  3335. // be its own thin LAZYFS proxying calls to MEMFS.
  3336. if (properties.contents) {
  3337. node.contents = properties.contents;
  3338. } else if (properties.url) {
  3339. node.contents = null;
  3340. node.url = properties.url;
  3341. }
  3342. // Add a function that defers querying the file size until it is asked the first time.
  3343. Object.defineProperties(node, {
  3344. usedBytes: {
  3345. get: function() { return this.contents.length; }
  3346. }
  3347. });
  3348. // override each stream op with one that tries to force load the lazy file first
  3349. var stream_ops = {};
  3350. var keys = Object.keys(node.stream_ops);
  3351. keys.forEach((key) => {
  3352. var fn = node.stream_ops[key];
  3353. stream_ops[key] = (...args) => {
  3354. FS.forceLoadFile(node);
  3355. return fn(...args);
  3356. };
  3357. });
  3358. function writeChunks(stream, buffer, offset, length, position) {
  3359. var contents = stream.node.contents;
  3360. if (position >= contents.length)
  3361. return 0;
  3362. var size = Math.min(contents.length - position, length);
  3363. assert(size >= 0);
  3364. if (contents.slice) { // normal array
  3365. for (var i = 0; i < size; i++) {
  3366. buffer[offset + i] = contents[position + i];
  3367. }
  3368. } else {
  3369. for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR
  3370. buffer[offset + i] = contents.get(position + i);
  3371. }
  3372. }
  3373. return size;
  3374. }
  3375. // use a custom read function
  3376. stream_ops.read = (stream, buffer, offset, length, position) => {
  3377. FS.forceLoadFile(node);
  3378. return writeChunks(stream, buffer, offset, length, position)
  3379. };
  3380. // use a custom mmap function
  3381. stream_ops.mmap = (stream, length, position, prot, flags) => {
  3382. FS.forceLoadFile(node);
  3383. var ptr = mmapAlloc(length);
  3384. if (!ptr) {
  3385. throw new FS.ErrnoError(48);
  3386. }
  3387. writeChunks(stream, HEAP8, ptr, length, position);
  3388. return { ptr, allocated: true };
  3389. };
  3390. node.stream_ops = stream_ops;
  3391. return node;
  3392. },
  3393. absolutePath() {
  3394. abort('FS.absolutePath has been removed; use PATH_FS.resolve instead');
  3395. },
  3396. createFolder() {
  3397. abort('FS.createFolder has been removed; use FS.mkdir instead');
  3398. },
  3399. createLink() {
  3400. abort('FS.createLink has been removed; use FS.symlink instead');
  3401. },
  3402. joinPath() {
  3403. abort('FS.joinPath has been removed; use PATH.join instead');
  3404. },
  3405. mmapAlloc() {
  3406. abort('FS.mmapAlloc has been replaced by the top level function mmapAlloc');
  3407. },
  3408. standardizePath() {
  3409. abort('FS.standardizePath has been removed; use PATH.normalize instead');
  3410. },
  3411. };
  3412. var SYSCALLS = {
  3413. DEFAULT_POLLMASK:5,
  3414. calculateAt(dirfd, path, allowEmpty) {
  3415. if (PATH.isAbs(path)) {
  3416. return path;
  3417. }
  3418. // relative path
  3419. var dir;
  3420. if (dirfd === -100) {
  3421. dir = FS.cwd();
  3422. } else {
  3423. var dirstream = SYSCALLS.getStreamFromFD(dirfd);
  3424. dir = dirstream.path;
  3425. }
  3426. if (path.length == 0) {
  3427. if (!allowEmpty) {
  3428. throw new FS.ErrnoError(44);;
  3429. }
  3430. return dir;
  3431. }
  3432. return dir + '/' + path;
  3433. },
  3434. writeStat(buf, stat) {
  3435. HEAP32[((buf)>>2)] = stat.dev;
  3436. HEAP32[(((buf)+(4))>>2)] = stat.mode;
  3437. HEAPU32[(((buf)+(8))>>2)] = stat.nlink;
  3438. HEAP32[(((buf)+(12))>>2)] = stat.uid;
  3439. HEAP32[(((buf)+(16))>>2)] = stat.gid;
  3440. HEAP32[(((buf)+(20))>>2)] = stat.rdev;
  3441. HEAP64[(((buf)+(24))>>3)] = BigInt(stat.size);
  3442. HEAP32[(((buf)+(32))>>2)] = 4096;
  3443. HEAP32[(((buf)+(36))>>2)] = stat.blocks;
  3444. var atime = stat.atime.getTime();
  3445. var mtime = stat.mtime.getTime();
  3446. var ctime = stat.ctime.getTime();
  3447. HEAP64[(((buf)+(40))>>3)] = BigInt(Math.floor(atime / 1000));
  3448. HEAPU32[(((buf)+(48))>>2)] = (atime % 1000) * 1000 * 1000;
  3449. HEAP64[(((buf)+(56))>>3)] = BigInt(Math.floor(mtime / 1000));
  3450. HEAPU32[(((buf)+(64))>>2)] = (mtime % 1000) * 1000 * 1000;
  3451. HEAP64[(((buf)+(72))>>3)] = BigInt(Math.floor(ctime / 1000));
  3452. HEAPU32[(((buf)+(80))>>2)] = (ctime % 1000) * 1000 * 1000;
  3453. HEAP64[(((buf)+(88))>>3)] = BigInt(stat.ino);
  3454. return 0;
  3455. },
  3456. writeStatFs(buf, stats) {
  3457. HEAP32[(((buf)+(4))>>2)] = stats.bsize;
  3458. HEAP32[(((buf)+(40))>>2)] = stats.bsize;
  3459. HEAP32[(((buf)+(8))>>2)] = stats.blocks;
  3460. HEAP32[(((buf)+(12))>>2)] = stats.bfree;
  3461. HEAP32[(((buf)+(16))>>2)] = stats.bavail;
  3462. HEAP32[(((buf)+(20))>>2)] = stats.files;
  3463. HEAP32[(((buf)+(24))>>2)] = stats.ffree;
  3464. HEAP32[(((buf)+(28))>>2)] = stats.fsid;
  3465. HEAP32[(((buf)+(44))>>2)] = stats.flags; // ST_NOSUID
  3466. HEAP32[(((buf)+(36))>>2)] = stats.namelen;
  3467. },
  3468. doMsync(addr, stream, len, flags, offset) {
  3469. if (!FS.isFile(stream.node.mode)) {
  3470. throw new FS.ErrnoError(43);
  3471. }
  3472. if (flags & 2) {
  3473. // MAP_PRIVATE calls need not to be synced back to underlying fs
  3474. return 0;
  3475. }
  3476. var buffer = HEAPU8.slice(addr, addr + len);
  3477. FS.msync(stream, buffer, offset, len, flags);
  3478. },
  3479. getStreamFromFD(fd) {
  3480. var stream = FS.getStreamChecked(fd);
  3481. return stream;
  3482. },
  3483. varargs:undefined,
  3484. getStr(ptr) {
  3485. var ret = UTF8ToString(ptr);
  3486. return ret;
  3487. },
  3488. };
  3489. function ___syscall_faccessat(dirfd, path, amode, flags) {
  3490. try {
  3491. path = SYSCALLS.getStr(path);
  3492. assert(flags === 0 || flags == 512);
  3493. path = SYSCALLS.calculateAt(dirfd, path);
  3494. if (amode & ~7) {
  3495. // need a valid mode
  3496. return -28;
  3497. }
  3498. var lookup = FS.lookupPath(path, { follow: true });
  3499. var node = lookup.node;
  3500. if (!node) {
  3501. return -44;
  3502. }
  3503. var perms = '';
  3504. if (amode & 4) perms += 'r';
  3505. if (amode & 2) perms += 'w';
  3506. if (amode & 1) perms += 'x';
  3507. if (perms /* otherwise, they've just passed F_OK */ && FS.nodePermissions(node, perms)) {
  3508. return -2;
  3509. }
  3510. return 0;
  3511. } catch (e) {
  3512. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  3513. return -e.errno;
  3514. }
  3515. }
  3516. /** @suppress {duplicate } */
  3517. var syscallGetVarargI = () => {
  3518. assert(SYSCALLS.varargs != undefined);
  3519. // the `+` prepended here is necessary to convince the JSCompiler that varargs is indeed a number.
  3520. var ret = HEAP32[((+SYSCALLS.varargs)>>2)];
  3521. SYSCALLS.varargs += 4;
  3522. return ret;
  3523. };
  3524. var syscallGetVarargP = syscallGetVarargI;
  3525. function ___syscall_fcntl64(fd, cmd, varargs) {
  3526. SYSCALLS.varargs = varargs;
  3527. try {
  3528. var stream = SYSCALLS.getStreamFromFD(fd);
  3529. switch (cmd) {
  3530. case 0: {
  3531. var arg = syscallGetVarargI();
  3532. if (arg < 0) {
  3533. return -28;
  3534. }
  3535. while (FS.streams[arg]) {
  3536. arg++;
  3537. }
  3538. var newStream;
  3539. newStream = FS.dupStream(stream, arg);
  3540. return newStream.fd;
  3541. }
  3542. case 1:
  3543. case 2:
  3544. return 0; // FD_CLOEXEC makes no sense for a single process.
  3545. case 3:
  3546. return stream.flags;
  3547. case 4: {
  3548. var arg = syscallGetVarargI();
  3549. stream.flags |= arg;
  3550. return 0;
  3551. }
  3552. case 12: {
  3553. var arg = syscallGetVarargP();
  3554. var offset = 0;
  3555. // We're always unlocked.
  3556. HEAP16[(((arg)+(offset))>>1)] = 2;
  3557. return 0;
  3558. }
  3559. case 13:
  3560. case 14:
  3561. return 0; // Pretend that the locking is successful.
  3562. }
  3563. return -28;
  3564. } catch (e) {
  3565. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  3566. return -e.errno;
  3567. }
  3568. }
  3569. var stringToUTF8 = (str, outPtr, maxBytesToWrite) => {
  3570. assert(typeof maxBytesToWrite == 'number', 'stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!');
  3571. return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);
  3572. };
  3573. function ___syscall_getcwd(buf, size) {
  3574. try {
  3575. if (size === 0) return -28;
  3576. var cwd = FS.cwd();
  3577. var cwdLengthInBytes = lengthBytesUTF8(cwd) + 1;
  3578. if (size < cwdLengthInBytes) return -68;
  3579. stringToUTF8(cwd, buf, size);
  3580. return cwdLengthInBytes;
  3581. } catch (e) {
  3582. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  3583. return -e.errno;
  3584. }
  3585. }
  3586. function ___syscall_ioctl(fd, op, varargs) {
  3587. SYSCALLS.varargs = varargs;
  3588. try {
  3589. var stream = SYSCALLS.getStreamFromFD(fd);
  3590. switch (op) {
  3591. case 21509: {
  3592. if (!stream.tty) return -59;
  3593. return 0;
  3594. }
  3595. case 21505: {
  3596. if (!stream.tty) return -59;
  3597. if (stream.tty.ops.ioctl_tcgets) {
  3598. var termios = stream.tty.ops.ioctl_tcgets(stream);
  3599. var argp = syscallGetVarargP();
  3600. HEAP32[((argp)>>2)] = termios.c_iflag || 0;
  3601. HEAP32[(((argp)+(4))>>2)] = termios.c_oflag || 0;
  3602. HEAP32[(((argp)+(8))>>2)] = termios.c_cflag || 0;
  3603. HEAP32[(((argp)+(12))>>2)] = termios.c_lflag || 0;
  3604. for (var i = 0; i < 32; i++) {
  3605. HEAP8[(argp + i)+(17)] = termios.c_cc[i] || 0;
  3606. }
  3607. return 0;
  3608. }
  3609. return 0;
  3610. }
  3611. case 21510:
  3612. case 21511:
  3613. case 21512: {
  3614. if (!stream.tty) return -59;
  3615. return 0; // no-op, not actually adjusting terminal settings
  3616. }
  3617. case 21506:
  3618. case 21507:
  3619. case 21508: {
  3620. if (!stream.tty) return -59;
  3621. if (stream.tty.ops.ioctl_tcsets) {
  3622. var argp = syscallGetVarargP();
  3623. var c_iflag = HEAP32[((argp)>>2)];
  3624. var c_oflag = HEAP32[(((argp)+(4))>>2)];
  3625. var c_cflag = HEAP32[(((argp)+(8))>>2)];
  3626. var c_lflag = HEAP32[(((argp)+(12))>>2)];
  3627. var c_cc = []
  3628. for (var i = 0; i < 32; i++) {
  3629. c_cc.push(HEAP8[(argp + i)+(17)]);
  3630. }
  3631. return stream.tty.ops.ioctl_tcsets(stream.tty, op, { c_iflag, c_oflag, c_cflag, c_lflag, c_cc });
  3632. }
  3633. return 0; // no-op, not actually adjusting terminal settings
  3634. }
  3635. case 21519: {
  3636. if (!stream.tty) return -59;
  3637. var argp = syscallGetVarargP();
  3638. HEAP32[((argp)>>2)] = 0;
  3639. return 0;
  3640. }
  3641. case 21520: {
  3642. if (!stream.tty) return -59;
  3643. return -28; // not supported
  3644. }
  3645. case 21531: {
  3646. var argp = syscallGetVarargP();
  3647. return FS.ioctl(stream, op, argp);
  3648. }
  3649. case 21523: {
  3650. // TODO: in theory we should write to the winsize struct that gets
  3651. // passed in, but for now musl doesn't read anything on it
  3652. if (!stream.tty) return -59;
  3653. if (stream.tty.ops.ioctl_tiocgwinsz) {
  3654. var winsize = stream.tty.ops.ioctl_tiocgwinsz(stream.tty);
  3655. var argp = syscallGetVarargP();
  3656. HEAP16[((argp)>>1)] = winsize[0];
  3657. HEAP16[(((argp)+(2))>>1)] = winsize[1];
  3658. }
  3659. return 0;
  3660. }
  3661. case 21524: {
  3662. // TODO: technically, this ioctl call should change the window size.
  3663. // but, since emscripten doesn't have any concept of a terminal window
  3664. // yet, we'll just silently throw it away as we do TIOCGWINSZ
  3665. if (!stream.tty) return -59;
  3666. return 0;
  3667. }
  3668. case 21515: {
  3669. if (!stream.tty) return -59;
  3670. return 0;
  3671. }
  3672. default: return -28; // not supported
  3673. }
  3674. } catch (e) {
  3675. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  3676. return -e.errno;
  3677. }
  3678. }
  3679. function ___syscall_openat(dirfd, path, flags, varargs) {
  3680. SYSCALLS.varargs = varargs;
  3681. try {
  3682. path = SYSCALLS.getStr(path);
  3683. path = SYSCALLS.calculateAt(dirfd, path);
  3684. var mode = varargs ? syscallGetVarargI() : 0;
  3685. return FS.open(path, flags, mode).fd;
  3686. } catch (e) {
  3687. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  3688. return -e.errno;
  3689. }
  3690. }
  3691. var __abort_js = () =>
  3692. abort('native code called abort()');
  3693. var isLeapYear = (year) => year%4 === 0 && (year%100 !== 0 || year%400 === 0);
  3694. var MONTH_DAYS_LEAP_CUMULATIVE = [0,31,60,91,121,152,182,213,244,274,305,335];
  3695. var MONTH_DAYS_REGULAR_CUMULATIVE = [0,31,59,90,120,151,181,212,243,273,304,334];
  3696. var ydayFromDate = (date) => {
  3697. var leap = isLeapYear(date.getFullYear());
  3698. var monthDaysCumulative = (leap ? MONTH_DAYS_LEAP_CUMULATIVE : MONTH_DAYS_REGULAR_CUMULATIVE);
  3699. var yday = monthDaysCumulative[date.getMonth()] + date.getDate() - 1; // -1 since it's days since Jan 1
  3700. return yday;
  3701. };
  3702. var INT53_MAX = 9007199254740992;
  3703. var INT53_MIN = -9007199254740992;
  3704. var bigintToI53Checked = (num) => (num < INT53_MIN || num > INT53_MAX) ? NaN : Number(num);
  3705. function __localtime_js(time, tmPtr) {
  3706. time = bigintToI53Checked(time);
  3707. var date = new Date(time*1000);
  3708. HEAP32[((tmPtr)>>2)] = date.getSeconds();
  3709. HEAP32[(((tmPtr)+(4))>>2)] = date.getMinutes();
  3710. HEAP32[(((tmPtr)+(8))>>2)] = date.getHours();
  3711. HEAP32[(((tmPtr)+(12))>>2)] = date.getDate();
  3712. HEAP32[(((tmPtr)+(16))>>2)] = date.getMonth();
  3713. HEAP32[(((tmPtr)+(20))>>2)] = date.getFullYear()-1900;
  3714. HEAP32[(((tmPtr)+(24))>>2)] = date.getDay();
  3715. var yday = ydayFromDate(date)|0;
  3716. HEAP32[(((tmPtr)+(28))>>2)] = yday;
  3717. HEAP32[(((tmPtr)+(36))>>2)] = -(date.getTimezoneOffset() * 60);
  3718. // Attention: DST is in December in South, and some regions don't have DST at all.
  3719. var start = new Date(date.getFullYear(), 0, 1);
  3720. var summerOffset = new Date(date.getFullYear(), 6, 1).getTimezoneOffset();
  3721. var winterOffset = start.getTimezoneOffset();
  3722. var dst = (summerOffset != winterOffset && date.getTimezoneOffset() == Math.min(winterOffset, summerOffset))|0;
  3723. HEAP32[(((tmPtr)+(32))>>2)] = dst;
  3724. ;
  3725. }
  3726. var __tzset_js = (timezone, daylight, std_name, dst_name) => {
  3727. // TODO: Use (malleable) environment variables instead of system settings.
  3728. var currentYear = new Date().getFullYear();
  3729. var winter = new Date(currentYear, 0, 1);
  3730. var summer = new Date(currentYear, 6, 1);
  3731. var winterOffset = winter.getTimezoneOffset();
  3732. var summerOffset = summer.getTimezoneOffset();
  3733. // Local standard timezone offset. Local standard time is not adjusted for
  3734. // daylight savings. This code uses the fact that getTimezoneOffset returns
  3735. // a greater value during Standard Time versus Daylight Saving Time (DST).
  3736. // Thus it determines the expected output during Standard Time, and it
  3737. // compares whether the output of the given date the same (Standard) or less
  3738. // (DST).
  3739. var stdTimezoneOffset = Math.max(winterOffset, summerOffset);
  3740. // timezone is specified as seconds west of UTC ("The external variable
  3741. // `timezone` shall be set to the difference, in seconds, between
  3742. // Coordinated Universal Time (UTC) and local standard time."), the same
  3743. // as returned by stdTimezoneOffset.
  3744. // See http://pubs.opengroup.org/onlinepubs/009695399/functions/tzset.html
  3745. HEAPU32[((timezone)>>2)] = stdTimezoneOffset * 60;
  3746. HEAP32[((daylight)>>2)] = Number(winterOffset != summerOffset);
  3747. var extractZone = (timezoneOffset) => {
  3748. // Why inverse sign?
  3749. // Read here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset
  3750. var sign = timezoneOffset >= 0 ? "-" : "+";
  3751. var absOffset = Math.abs(timezoneOffset)
  3752. var hours = String(Math.floor(absOffset / 60)).padStart(2, "0");
  3753. var minutes = String(absOffset % 60).padStart(2, "0");
  3754. return `UTC${sign}${hours}${minutes}`;
  3755. }
  3756. var winterName = extractZone(winterOffset);
  3757. var summerName = extractZone(summerOffset);
  3758. assert(winterName);
  3759. assert(summerName);
  3760. assert(lengthBytesUTF8(winterName) <= 16, `timezone name truncated to fit in TZNAME_MAX (${winterName})`);
  3761. assert(lengthBytesUTF8(summerName) <= 16, `timezone name truncated to fit in TZNAME_MAX (${summerName})`);
  3762. if (summerOffset < winterOffset) {
  3763. // Northern hemisphere
  3764. stringToUTF8(winterName, std_name, 17);
  3765. stringToUTF8(summerName, dst_name, 17);
  3766. } else {
  3767. stringToUTF8(winterName, dst_name, 17);
  3768. stringToUTF8(summerName, std_name, 17);
  3769. }
  3770. };
  3771. var _emscripten_get_now = () => performance.now();
  3772. var _emscripten_date_now = () => Date.now();
  3773. var nowIsMonotonic = 1;
  3774. var checkWasiClock = (clock_id) => clock_id >= 0 && clock_id <= 3;
  3775. function _clock_time_get(clk_id, ignored_precision, ptime) {
  3776. ignored_precision = bigintToI53Checked(ignored_precision);
  3777. if (!checkWasiClock(clk_id)) {
  3778. return 28;
  3779. }
  3780. var now;
  3781. // all wasi clocks but realtime are monotonic
  3782. if (clk_id === 0) {
  3783. now = _emscripten_date_now();
  3784. } else if (nowIsMonotonic) {
  3785. now = _emscripten_get_now();
  3786. } else {
  3787. return 52;
  3788. }
  3789. // "now" is in ms, and wasi times are in ns.
  3790. var nsec = Math.round(now * 1000 * 1000);
  3791. HEAP64[((ptime)>>3)] = BigInt(nsec);
  3792. return 0;
  3793. ;
  3794. }
  3795. var readEmAsmArgsArray = [];
  3796. var readEmAsmArgs = (sigPtr, buf) => {
  3797. // Nobody should have mutated _readEmAsmArgsArray underneath us to be something else than an array.
  3798. assert(Array.isArray(readEmAsmArgsArray));
  3799. // The input buffer is allocated on the stack, so it must be stack-aligned.
  3800. assert(buf % 16 == 0);
  3801. readEmAsmArgsArray.length = 0;
  3802. var ch;
  3803. // Most arguments are i32s, so shift the buffer pointer so it is a plain
  3804. // index into HEAP32.
  3805. while (ch = HEAPU8[sigPtr++]) {
  3806. var chr = String.fromCharCode(ch);
  3807. var validChars = ['d', 'f', 'i', 'p'];
  3808. // In WASM_BIGINT mode we support passing i64 values as bigint.
  3809. validChars.push('j');
  3810. assert(validChars.includes(chr), `Invalid character ${ch}("${chr}") in readEmAsmArgs! Use only [${validChars}], and do not specify "v" for void return argument.`);
  3811. // Floats are always passed as doubles, so all types except for 'i'
  3812. // are 8 bytes and require alignment.
  3813. var wide = (ch != 105);
  3814. wide &= (ch != 112);
  3815. buf += wide && (buf % 8) ? 4 : 0;
  3816. readEmAsmArgsArray.push(
  3817. // Special case for pointers under wasm64 or CAN_ADDRESS_2GB mode.
  3818. ch == 112 ? HEAPU32[((buf)>>2)] :
  3819. ch == 106 ? HEAP64[((buf)>>3)] :
  3820. ch == 105 ?
  3821. HEAP32[((buf)>>2)] :
  3822. HEAPF64[((buf)>>3)]
  3823. );
  3824. buf += wide ? 8 : 4;
  3825. }
  3826. return readEmAsmArgsArray;
  3827. };
  3828. var runEmAsmFunction = (code, sigPtr, argbuf) => {
  3829. var args = readEmAsmArgs(sigPtr, argbuf);
  3830. 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.`);
  3831. return ASM_CONSTS[code](...args);
  3832. };
  3833. var _emscripten_asm_const_int = (code, sigPtr, argbuf) => {
  3834. return runEmAsmFunction(code, sigPtr, argbuf);
  3835. };
  3836. var onExits = [];
  3837. var addOnExit = (cb) => onExits.unshift(cb);
  3838. var JSEvents = {
  3839. memcpy(target, src, size) {
  3840. HEAP8.set(HEAP8.subarray(src, src + size), target);
  3841. },
  3842. removeAllEventListeners() {
  3843. while (JSEvents.eventHandlers.length) {
  3844. JSEvents._removeHandler(JSEvents.eventHandlers.length - 1);
  3845. }
  3846. JSEvents.deferredCalls = [];
  3847. },
  3848. inEventHandler:0,
  3849. deferredCalls:[],
  3850. deferCall(targetFunction, precedence, argsList) {
  3851. function arraysHaveEqualContent(arrA, arrB) {
  3852. if (arrA.length != arrB.length) return false;
  3853. for (var i in arrA) {
  3854. if (arrA[i] != arrB[i]) return false;
  3855. }
  3856. return true;
  3857. }
  3858. // Test if the given call was already queued, and if so, don't add it again.
  3859. for (var call of JSEvents.deferredCalls) {
  3860. if (call.targetFunction == targetFunction && arraysHaveEqualContent(call.argsList, argsList)) {
  3861. return;
  3862. }
  3863. }
  3864. JSEvents.deferredCalls.push({
  3865. targetFunction,
  3866. precedence,
  3867. argsList
  3868. });
  3869. JSEvents.deferredCalls.sort((x,y) => x.precedence < y.precedence);
  3870. },
  3871. removeDeferredCalls(targetFunction) {
  3872. JSEvents.deferredCalls = JSEvents.deferredCalls.filter((call) => call.targetFunction != targetFunction);
  3873. },
  3874. canPerformEventHandlerRequests() {
  3875. if (navigator.userActivation) {
  3876. // Verify against transient activation status from UserActivation API
  3877. // whether it is possible to perform a request here without needing to defer. See
  3878. // https://developer.mozilla.org/en-US/docs/Web/Security/User_activation#transient_activation
  3879. // and https://caniuse.com/mdn-api_useractivation
  3880. // At the time of writing, Firefox does not support this API: https://bugzilla.mozilla.org/show_bug.cgi?id=1791079
  3881. return navigator.userActivation.isActive;
  3882. }
  3883. return JSEvents.inEventHandler && JSEvents.currentEventHandler.allowsDeferredCalls;
  3884. },
  3885. runDeferredCalls() {
  3886. if (!JSEvents.canPerformEventHandlerRequests()) {
  3887. return;
  3888. }
  3889. var deferredCalls = JSEvents.deferredCalls;
  3890. JSEvents.deferredCalls = [];
  3891. for (var call of deferredCalls) {
  3892. call.targetFunction(...call.argsList);
  3893. }
  3894. },
  3895. eventHandlers:[],
  3896. removeAllHandlersOnTarget:(target, eventTypeString) => {
  3897. for (var i = 0; i < JSEvents.eventHandlers.length; ++i) {
  3898. if (JSEvents.eventHandlers[i].target == target &&
  3899. (!eventTypeString || eventTypeString == JSEvents.eventHandlers[i].eventTypeString)) {
  3900. JSEvents._removeHandler(i--);
  3901. }
  3902. }
  3903. },
  3904. _removeHandler(i) {
  3905. var h = JSEvents.eventHandlers[i];
  3906. h.target.removeEventListener(h.eventTypeString, h.eventListenerFunc, h.useCapture);
  3907. JSEvents.eventHandlers.splice(i, 1);
  3908. },
  3909. registerOrRemoveHandler(eventHandler) {
  3910. if (!eventHandler.target) {
  3911. err('registerOrRemoveHandler: the target element for event handler registration does not exist, when processing the following event handler registration:');
  3912. console.dir(eventHandler);
  3913. return -4;
  3914. }
  3915. if (eventHandler.callbackfunc) {
  3916. eventHandler.eventListenerFunc = function(event) {
  3917. // Increment nesting count for the event handler.
  3918. ++JSEvents.inEventHandler;
  3919. JSEvents.currentEventHandler = eventHandler;
  3920. // Process any old deferred calls the user has placed.
  3921. JSEvents.runDeferredCalls();
  3922. // Process the actual event, calls back to user C code handler.
  3923. eventHandler.handlerFunc(event);
  3924. // Process any new deferred calls that were placed right now from this event handler.
  3925. JSEvents.runDeferredCalls();
  3926. // Out of event handler - restore nesting count.
  3927. --JSEvents.inEventHandler;
  3928. };
  3929. eventHandler.target.addEventListener(eventHandler.eventTypeString,
  3930. eventHandler.eventListenerFunc,
  3931. eventHandler.useCapture);
  3932. JSEvents.eventHandlers.push(eventHandler);
  3933. } else {
  3934. for (var i = 0; i < JSEvents.eventHandlers.length; ++i) {
  3935. if (JSEvents.eventHandlers[i].target == eventHandler.target
  3936. && JSEvents.eventHandlers[i].eventTypeString == eventHandler.eventTypeString) {
  3937. JSEvents._removeHandler(i--);
  3938. }
  3939. }
  3940. }
  3941. return 0;
  3942. },
  3943. getNodeNameForTarget(target) {
  3944. if (!target) return '';
  3945. if (target == window) return '#window';
  3946. if (target == screen) return '#screen';
  3947. return target?.nodeName || '';
  3948. },
  3949. fullscreenEnabled() {
  3950. return document.fullscreenEnabled
  3951. // Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitFullscreenEnabled.
  3952. // TODO: If Safari at some point ships with unprefixed version, update the version check above.
  3953. || document.webkitFullscreenEnabled
  3954. ;
  3955. },
  3956. };
  3957. var maybeCStringToJsString = (cString) => {
  3958. // "cString > 2" checks if the input is a number, and isn't of the special
  3959. // values we accept here, EMSCRIPTEN_EVENT_TARGET_* (which map to 0, 1, 2).
  3960. // In other words, if cString > 2 then it's a pointer to a valid place in
  3961. // memory, and points to a C string.
  3962. return cString > 2 ? UTF8ToString(cString) : cString;
  3963. };
  3964. /** @type {Object} */
  3965. var specialHTMLTargets = [0, typeof document != 'undefined' ? document : 0, typeof window != 'undefined' ? window : 0];
  3966. var findEventTarget = (target) => {
  3967. target = maybeCStringToJsString(target);
  3968. var domElement = specialHTMLTargets[target] || (typeof document != 'undefined' ? document.querySelector(target) : null);
  3969. return domElement;
  3970. };
  3971. var getBoundingClientRect = (e) => specialHTMLTargets.indexOf(e) < 0 ? e.getBoundingClientRect() : {'left':0,'top':0};
  3972. var _emscripten_get_element_css_size = (target, width, height) => {
  3973. target = findEventTarget(target);
  3974. if (!target) return -4;
  3975. var rect = getBoundingClientRect(target);
  3976. HEAPF64[((width)>>3)] = rect.width;
  3977. HEAPF64[((height)>>3)] = rect.height;
  3978. return 0;
  3979. };
  3980. var fillGamepadEventData = (eventStruct, e) => {
  3981. HEAPF64[((eventStruct)>>3)] = e.timestamp;
  3982. for (var i = 0; i < e.axes.length; ++i) {
  3983. HEAPF64[(((eventStruct+i*8)+(16))>>3)] = e.axes[i];
  3984. }
  3985. for (var i = 0; i < e.buttons.length; ++i) {
  3986. if (typeof e.buttons[i] == 'object') {
  3987. HEAPF64[(((eventStruct+i*8)+(528))>>3)] = e.buttons[i].value;
  3988. } else {
  3989. HEAPF64[(((eventStruct+i*8)+(528))>>3)] = e.buttons[i];
  3990. }
  3991. }
  3992. for (var i = 0; i < e.buttons.length; ++i) {
  3993. if (typeof e.buttons[i] == 'object') {
  3994. HEAP8[(eventStruct+i)+(1040)] = e.buttons[i].pressed;
  3995. } else {
  3996. // Assigning a boolean to HEAP32, that's ok, but Closure would like to warn about it:
  3997. /** @suppress {checkTypes} */
  3998. HEAP8[(eventStruct+i)+(1040)] = e.buttons[i] == 1;
  3999. }
  4000. }
  4001. HEAP8[(eventStruct)+(1104)] = e.connected;
  4002. HEAP32[(((eventStruct)+(1108))>>2)] = e.index;
  4003. HEAP32[(((eventStruct)+(8))>>2)] = e.axes.length;
  4004. HEAP32[(((eventStruct)+(12))>>2)] = e.buttons.length;
  4005. stringToUTF8(e.id, eventStruct + 1112, 64);
  4006. stringToUTF8(e.mapping, eventStruct + 1176, 64);
  4007. };
  4008. var _emscripten_get_gamepad_status = (index, gamepadState) => {
  4009. 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!';
  4010. // INVALID_PARAM is returned on a Gamepad index that never was there.
  4011. if (index < 0 || index >= JSEvents.lastGamepadState.length) return -5;
  4012. // NO_DATA is returned on a Gamepad index that was removed.
  4013. // For previously disconnected gamepads there should be an empty slot (null/undefined/false) at the index.
  4014. // This is because gamepads must keep their original position in the array.
  4015. // For example, removing the first of two gamepads produces [null/undefined/false, gamepad].
  4016. if (!JSEvents.lastGamepadState[index]) return -7;
  4017. fillGamepadEventData(gamepadState, JSEvents.lastGamepadState[index]);
  4018. return 0;
  4019. };
  4020. var _emscripten_get_num_gamepads = () => {
  4021. 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!';
  4022. // N.B. Do not call emscripten_get_num_gamepads() unless having first called emscripten_sample_gamepad_data(), and that has returned EMSCRIPTEN_RESULT_SUCCESS.
  4023. // Otherwise the following line will throw an exception.
  4024. return JSEvents.lastGamepadState.length;
  4025. };
  4026. var GLctx;
  4027. var webgl_enable_ANGLE_instanced_arrays = (ctx) => {
  4028. // Extension available in WebGL 1 from Firefox 26 and Google Chrome 30 onwards. Core feature in WebGL 2.
  4029. var ext = ctx.getExtension('ANGLE_instanced_arrays');
  4030. // Because this extension is a core function in WebGL 2, assign the extension entry points in place of
  4031. // where the core functions will reside in WebGL 2. This way the calling code can call these without
  4032. // having to dynamically branch depending if running against WebGL 1 or WebGL 2.
  4033. if (ext) {
  4034. ctx['vertexAttribDivisor'] = (index, divisor) => ext['vertexAttribDivisorANGLE'](index, divisor);
  4035. ctx['drawArraysInstanced'] = (mode, first, count, primcount) => ext['drawArraysInstancedANGLE'](mode, first, count, primcount);
  4036. ctx['drawElementsInstanced'] = (mode, count, type, indices, primcount) => ext['drawElementsInstancedANGLE'](mode, count, type, indices, primcount);
  4037. return 1;
  4038. }
  4039. };
  4040. var webgl_enable_OES_vertex_array_object = (ctx) => {
  4041. // Extension available in WebGL 1 from Firefox 25 and WebKit 536.28/desktop Safari 6.0.3 onwards. Core feature in WebGL 2.
  4042. var ext = ctx.getExtension('OES_vertex_array_object');
  4043. if (ext) {
  4044. ctx['createVertexArray'] = () => ext['createVertexArrayOES']();
  4045. ctx['deleteVertexArray'] = (vao) => ext['deleteVertexArrayOES'](vao);
  4046. ctx['bindVertexArray'] = (vao) => ext['bindVertexArrayOES'](vao);
  4047. ctx['isVertexArray'] = (vao) => ext['isVertexArrayOES'](vao);
  4048. return 1;
  4049. }
  4050. };
  4051. var webgl_enable_WEBGL_draw_buffers = (ctx) => {
  4052. // Extension available in WebGL 1 from Firefox 28 onwards. Core feature in WebGL 2.
  4053. var ext = ctx.getExtension('WEBGL_draw_buffers');
  4054. if (ext) {
  4055. ctx['drawBuffers'] = (n, bufs) => ext['drawBuffersWEBGL'](n, bufs);
  4056. return 1;
  4057. }
  4058. };
  4059. var webgl_enable_EXT_polygon_offset_clamp = (ctx) =>
  4060. !!(ctx.extPolygonOffsetClamp = ctx.getExtension('EXT_polygon_offset_clamp'));
  4061. var webgl_enable_EXT_clip_control = (ctx) =>
  4062. !!(ctx.extClipControl = ctx.getExtension('EXT_clip_control'));
  4063. var webgl_enable_WEBGL_polygon_mode = (ctx) =>
  4064. !!(ctx.webglPolygonMode = ctx.getExtension('WEBGL_polygon_mode'));
  4065. var webgl_enable_WEBGL_multi_draw = (ctx) =>
  4066. // Closure is expected to be allowed to minify the '.multiDrawWebgl' property, so not accessing it quoted.
  4067. !!(ctx.multiDrawWebgl = ctx.getExtension('WEBGL_multi_draw'));
  4068. var getEmscriptenSupportedExtensions = (ctx) => {
  4069. // Restrict the list of advertised extensions to those that we actually
  4070. // support.
  4071. var supportedExtensions = [
  4072. // WebGL 1 extensions
  4073. 'ANGLE_instanced_arrays',
  4074. 'EXT_blend_minmax',
  4075. 'EXT_disjoint_timer_query',
  4076. 'EXT_frag_depth',
  4077. 'EXT_shader_texture_lod',
  4078. 'EXT_sRGB',
  4079. 'OES_element_index_uint',
  4080. 'OES_fbo_render_mipmap',
  4081. 'OES_standard_derivatives',
  4082. 'OES_texture_float',
  4083. 'OES_texture_half_float',
  4084. 'OES_texture_half_float_linear',
  4085. 'OES_vertex_array_object',
  4086. 'WEBGL_color_buffer_float',
  4087. 'WEBGL_depth_texture',
  4088. 'WEBGL_draw_buffers',
  4089. // WebGL 1 and WebGL 2 extensions
  4090. 'EXT_clip_control',
  4091. 'EXT_color_buffer_half_float',
  4092. 'EXT_depth_clamp',
  4093. 'EXT_float_blend',
  4094. 'EXT_polygon_offset_clamp',
  4095. 'EXT_texture_compression_bptc',
  4096. 'EXT_texture_compression_rgtc',
  4097. 'EXT_texture_filter_anisotropic',
  4098. 'KHR_parallel_shader_compile',
  4099. 'OES_texture_float_linear',
  4100. 'WEBGL_blend_func_extended',
  4101. 'WEBGL_compressed_texture_astc',
  4102. 'WEBGL_compressed_texture_etc',
  4103. 'WEBGL_compressed_texture_etc1',
  4104. 'WEBGL_compressed_texture_s3tc',
  4105. 'WEBGL_compressed_texture_s3tc_srgb',
  4106. 'WEBGL_debug_renderer_info',
  4107. 'WEBGL_debug_shaders',
  4108. 'WEBGL_lose_context',
  4109. 'WEBGL_multi_draw',
  4110. 'WEBGL_polygon_mode'
  4111. ];
  4112. // .getSupportedExtensions() can return null if context is lost, so coerce to empty array.
  4113. return (ctx.getSupportedExtensions() || []).filter(ext => supportedExtensions.includes(ext));
  4114. };
  4115. var GL = {
  4116. counter:1,
  4117. buffers:[],
  4118. programs:[],
  4119. framebuffers:[],
  4120. renderbuffers:[],
  4121. textures:[],
  4122. shaders:[],
  4123. vaos:[],
  4124. contexts:[],
  4125. offscreenCanvases:{
  4126. },
  4127. queries:[],
  4128. stringCache:{
  4129. },
  4130. unpackAlignment:4,
  4131. unpackRowLength:0,
  4132. recordError:(errorCode) => {
  4133. if (!GL.lastError) {
  4134. GL.lastError = errorCode;
  4135. }
  4136. },
  4137. getNewId:(table) => {
  4138. var ret = GL.counter++;
  4139. for (var i = table.length; i < ret; i++) {
  4140. table[i] = null;
  4141. }
  4142. return ret;
  4143. },
  4144. genObject:(n, buffers, createFunction, objectTable
  4145. ) => {
  4146. for (var i = 0; i < n; i++) {
  4147. var buffer = GLctx[createFunction]();
  4148. var id = buffer && GL.getNewId(objectTable);
  4149. if (buffer) {
  4150. buffer.name = id;
  4151. objectTable[id] = buffer;
  4152. } else {
  4153. GL.recordError(0x502 /* GL_INVALID_OPERATION */);
  4154. }
  4155. HEAP32[(((buffers)+(i*4))>>2)] = id;
  4156. }
  4157. },
  4158. getSource:(shader, count, string, length) => {
  4159. var source = '';
  4160. for (var i = 0; i < count; ++i) {
  4161. var len = length ? HEAPU32[(((length)+(i*4))>>2)] : undefined;
  4162. source += UTF8ToString(HEAPU32[(((string)+(i*4))>>2)], len);
  4163. }
  4164. return source;
  4165. },
  4166. createContext:(/** @type {HTMLCanvasElement} */ canvas, webGLContextAttributes) => {
  4167. // BUG: Workaround Safari WebGL issue: After successfully acquiring WebGL
  4168. // context on a canvas, calling .getContext() will always return that
  4169. // context independent of which 'webgl' or 'webgl2'
  4170. // context version was passed. See:
  4171. // https://bugs.webkit.org/show_bug.cgi?id=222758
  4172. // and:
  4173. // https://github.com/emscripten-core/emscripten/issues/13295.
  4174. // TODO: Once the bug is fixed and shipped in Safari, adjust the Safari
  4175. // version field in above check.
  4176. if (!canvas.getContextSafariWebGL2Fixed) {
  4177. canvas.getContextSafariWebGL2Fixed = canvas.getContext;
  4178. /** @type {function(this:HTMLCanvasElement, string, (Object|null)=): (Object|null)} */
  4179. function fixedGetContext(ver, attrs) {
  4180. var gl = canvas.getContextSafariWebGL2Fixed(ver, attrs);
  4181. return ((ver == 'webgl') == (gl instanceof WebGLRenderingContext)) ? gl : null;
  4182. }
  4183. canvas.getContext = fixedGetContext;
  4184. }
  4185. var ctx =
  4186. (canvas.getContext("webgl", webGLContextAttributes)
  4187. // https://caniuse.com/#feat=webgl
  4188. );
  4189. if (!ctx) return 0;
  4190. var handle = GL.registerContext(ctx, webGLContextAttributes);
  4191. return handle;
  4192. },
  4193. registerContext:(ctx, webGLContextAttributes) => {
  4194. // without pthreads a context is just an integer ID
  4195. var handle = GL.getNewId(GL.contexts);
  4196. var context = {
  4197. handle,
  4198. attributes: webGLContextAttributes,
  4199. version: webGLContextAttributes.majorVersion,
  4200. GLctx: ctx
  4201. };
  4202. // Store the created context object so that we can access the context
  4203. // given a canvas without having to pass the parameters again.
  4204. if (ctx.canvas) ctx.canvas.GLctxObject = context;
  4205. GL.contexts[handle] = context;
  4206. if (typeof webGLContextAttributes.enableExtensionsByDefault == 'undefined' || webGLContextAttributes.enableExtensionsByDefault) {
  4207. GL.initExtensions(context);
  4208. }
  4209. return handle;
  4210. },
  4211. makeContextCurrent:(contextHandle) => {
  4212. // Active Emscripten GL layer context object.
  4213. GL.currentContext = GL.contexts[contextHandle];
  4214. // Active WebGL context object.
  4215. Module['ctx'] = GLctx = GL.currentContext?.GLctx;
  4216. return !(contextHandle && !GLctx);
  4217. },
  4218. getContext:(contextHandle) => {
  4219. return GL.contexts[contextHandle];
  4220. },
  4221. deleteContext:(contextHandle) => {
  4222. if (GL.currentContext === GL.contexts[contextHandle]) {
  4223. GL.currentContext = null;
  4224. }
  4225. if (typeof JSEvents == 'object') {
  4226. // Release all JS event handlers on the DOM element that the GL context is
  4227. // associated with since the context is now deleted.
  4228. JSEvents.removeAllHandlersOnTarget(GL.contexts[contextHandle].GLctx.canvas);
  4229. }
  4230. // Make sure the canvas object no longer refers to the context object so
  4231. // there are no GC surprises.
  4232. if (GL.contexts[contextHandle]?.GLctx.canvas) {
  4233. GL.contexts[contextHandle].GLctx.canvas.GLctxObject = undefined;
  4234. }
  4235. GL.contexts[contextHandle] = null;
  4236. },
  4237. initExtensions:(context) => {
  4238. // If this function is called without a specific context object, init the
  4239. // extensions of the currently active context.
  4240. context ||= GL.currentContext;
  4241. if (context.initExtensionsDone) return;
  4242. context.initExtensionsDone = true;
  4243. var GLctx = context.GLctx;
  4244. // Detect the presence of a few extensions manually, ction GL interop
  4245. // layer itself will need to know if they exist.
  4246. // Extensions that are available in both WebGL 1 and WebGL 2
  4247. webgl_enable_WEBGL_multi_draw(GLctx);
  4248. webgl_enable_EXT_polygon_offset_clamp(GLctx);
  4249. webgl_enable_EXT_clip_control(GLctx);
  4250. webgl_enable_WEBGL_polygon_mode(GLctx);
  4251. // Extensions that are only available in WebGL 1 (the calls will be no-ops
  4252. // if called on a WebGL 2 context active)
  4253. webgl_enable_ANGLE_instanced_arrays(GLctx);
  4254. webgl_enable_OES_vertex_array_object(GLctx);
  4255. webgl_enable_WEBGL_draw_buffers(GLctx);
  4256. {
  4257. GLctx.disjointTimerQueryExt = GLctx.getExtension("EXT_disjoint_timer_query");
  4258. }
  4259. getEmscriptenSupportedExtensions(GLctx).forEach((ext) => {
  4260. // WEBGL_lose_context, WEBGL_debug_renderer_info and WEBGL_debug_shaders
  4261. // are not enabled by default.
  4262. if (!ext.includes('lose_context') && !ext.includes('debug')) {
  4263. // Call .getExtension() to enable that extension permanently.
  4264. GLctx.getExtension(ext);
  4265. }
  4266. });
  4267. },
  4268. };
  4269. /** @suppress {duplicate } */
  4270. var _glActiveTexture = (x0) => GLctx.activeTexture(x0);
  4271. var _emscripten_glActiveTexture = _glActiveTexture;
  4272. /** @suppress {duplicate } */
  4273. var _glAttachShader = (program, shader) => {
  4274. GLctx.attachShader(GL.programs[program], GL.shaders[shader]);
  4275. };
  4276. var _emscripten_glAttachShader = _glAttachShader;
  4277. /** @suppress {duplicate } */
  4278. var _glBeginQueryEXT = (target, id) => {
  4279. GLctx.disjointTimerQueryExt['beginQueryEXT'](target, GL.queries[id]);
  4280. };
  4281. var _emscripten_glBeginQueryEXT = _glBeginQueryEXT;
  4282. /** @suppress {duplicate } */
  4283. var _glBindAttribLocation = (program, index, name) => {
  4284. GLctx.bindAttribLocation(GL.programs[program], index, UTF8ToString(name));
  4285. };
  4286. var _emscripten_glBindAttribLocation = _glBindAttribLocation;
  4287. /** @suppress {duplicate } */
  4288. var _glBindBuffer = (target, buffer) => {
  4289. GLctx.bindBuffer(target, GL.buffers[buffer]);
  4290. };
  4291. var _emscripten_glBindBuffer = _glBindBuffer;
  4292. /** @suppress {duplicate } */
  4293. var _glBindFramebuffer = (target, framebuffer) => {
  4294. GLctx.bindFramebuffer(target, GL.framebuffers[framebuffer]);
  4295. };
  4296. var _emscripten_glBindFramebuffer = _glBindFramebuffer;
  4297. /** @suppress {duplicate } */
  4298. var _glBindRenderbuffer = (target, renderbuffer) => {
  4299. GLctx.bindRenderbuffer(target, GL.renderbuffers[renderbuffer]);
  4300. };
  4301. var _emscripten_glBindRenderbuffer = _glBindRenderbuffer;
  4302. /** @suppress {duplicate } */
  4303. var _glBindTexture = (target, texture) => {
  4304. GLctx.bindTexture(target, GL.textures[texture]);
  4305. };
  4306. var _emscripten_glBindTexture = _glBindTexture;
  4307. /** @suppress {duplicate } */
  4308. var _glBindVertexArray = (vao) => {
  4309. GLctx.bindVertexArray(GL.vaos[vao]);
  4310. };
  4311. /** @suppress {duplicate } */
  4312. var _glBindVertexArrayOES = _glBindVertexArray;
  4313. var _emscripten_glBindVertexArrayOES = _glBindVertexArrayOES;
  4314. /** @suppress {duplicate } */
  4315. var _glBlendColor = (x0, x1, x2, x3) => GLctx.blendColor(x0, x1, x2, x3);
  4316. var _emscripten_glBlendColor = _glBlendColor;
  4317. /** @suppress {duplicate } */
  4318. var _glBlendEquation = (x0) => GLctx.blendEquation(x0);
  4319. var _emscripten_glBlendEquation = _glBlendEquation;
  4320. /** @suppress {duplicate } */
  4321. var _glBlendEquationSeparate = (x0, x1) => GLctx.blendEquationSeparate(x0, x1);
  4322. var _emscripten_glBlendEquationSeparate = _glBlendEquationSeparate;
  4323. /** @suppress {duplicate } */
  4324. var _glBlendFunc = (x0, x1) => GLctx.blendFunc(x0, x1);
  4325. var _emscripten_glBlendFunc = _glBlendFunc;
  4326. /** @suppress {duplicate } */
  4327. var _glBlendFuncSeparate = (x0, x1, x2, x3) => GLctx.blendFuncSeparate(x0, x1, x2, x3);
  4328. var _emscripten_glBlendFuncSeparate = _glBlendFuncSeparate;
  4329. /** @suppress {duplicate } */
  4330. var _glBufferData = (target, size, data, usage) => {
  4331. // N.b. here first form specifies a heap subarray, second form an integer
  4332. // size, so the ?: code here is polymorphic. It is advised to avoid
  4333. // randomly mixing both uses in calling code, to avoid any potential JS
  4334. // engine JIT issues.
  4335. GLctx.bufferData(target, data ? HEAPU8.subarray(data, data+size) : size, usage);
  4336. };
  4337. var _emscripten_glBufferData = _glBufferData;
  4338. /** @suppress {duplicate } */
  4339. var _glBufferSubData = (target, offset, size, data) => {
  4340. GLctx.bufferSubData(target, offset, HEAPU8.subarray(data, data+size));
  4341. };
  4342. var _emscripten_glBufferSubData = _glBufferSubData;
  4343. /** @suppress {duplicate } */
  4344. var _glCheckFramebufferStatus = (x0) => GLctx.checkFramebufferStatus(x0);
  4345. var _emscripten_glCheckFramebufferStatus = _glCheckFramebufferStatus;
  4346. /** @suppress {duplicate } */
  4347. var _glClear = (x0) => GLctx.clear(x0);
  4348. var _emscripten_glClear = _glClear;
  4349. /** @suppress {duplicate } */
  4350. var _glClearColor = (x0, x1, x2, x3) => GLctx.clearColor(x0, x1, x2, x3);
  4351. var _emscripten_glClearColor = _glClearColor;
  4352. /** @suppress {duplicate } */
  4353. var _glClearDepthf = (x0) => GLctx.clearDepth(x0);
  4354. var _emscripten_glClearDepthf = _glClearDepthf;
  4355. /** @suppress {duplicate } */
  4356. var _glClearStencil = (x0) => GLctx.clearStencil(x0);
  4357. var _emscripten_glClearStencil = _glClearStencil;
  4358. /** @suppress {duplicate } */
  4359. var _glClipControlEXT = (origin, depth) => {
  4360. GLctx.extClipControl['clipControlEXT'](origin, depth);
  4361. };
  4362. var _emscripten_glClipControlEXT = _glClipControlEXT;
  4363. /** @suppress {duplicate } */
  4364. var _glColorMask = (red, green, blue, alpha) => {
  4365. GLctx.colorMask(!!red, !!green, !!blue, !!alpha);
  4366. };
  4367. var _emscripten_glColorMask = _glColorMask;
  4368. /** @suppress {duplicate } */
  4369. var _glCompileShader = (shader) => {
  4370. GLctx.compileShader(GL.shaders[shader]);
  4371. };
  4372. var _emscripten_glCompileShader = _glCompileShader;
  4373. /** @suppress {duplicate } */
  4374. var _glCompressedTexImage2D = (target, level, internalFormat, width, height, border, imageSize, data) => {
  4375. // `data` may be null here, which means "allocate uniniitalized space but
  4376. // don't upload" in GLES parlance, but `compressedTexImage2D` requires the
  4377. // final data parameter, so we simply pass a heap view starting at zero
  4378. // effectively uploading whatever happens to be near address zero. See
  4379. // https://github.com/emscripten-core/emscripten/issues/19300.
  4380. GLctx.compressedTexImage2D(target, level, internalFormat, width, height, border, HEAPU8.subarray((data), data+imageSize));
  4381. };
  4382. var _emscripten_glCompressedTexImage2D = _glCompressedTexImage2D;
  4383. /** @suppress {duplicate } */
  4384. var _glCompressedTexSubImage2D = (target, level, xoffset, yoffset, width, height, format, imageSize, data) => {
  4385. GLctx.compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, HEAPU8.subarray((data), data+imageSize));
  4386. };
  4387. var _emscripten_glCompressedTexSubImage2D = _glCompressedTexSubImage2D;
  4388. /** @suppress {duplicate } */
  4389. var _glCopyTexImage2D = (x0, x1, x2, x3, x4, x5, x6, x7) => GLctx.copyTexImage2D(x0, x1, x2, x3, x4, x5, x6, x7);
  4390. var _emscripten_glCopyTexImage2D = _glCopyTexImage2D;
  4391. /** @suppress {duplicate } */
  4392. var _glCopyTexSubImage2D = (x0, x1, x2, x3, x4, x5, x6, x7) => GLctx.copyTexSubImage2D(x0, x1, x2, x3, x4, x5, x6, x7);
  4393. var _emscripten_glCopyTexSubImage2D = _glCopyTexSubImage2D;
  4394. /** @suppress {duplicate } */
  4395. var _glCreateProgram = () => {
  4396. var id = GL.getNewId(GL.programs);
  4397. var program = GLctx.createProgram();
  4398. // Store additional information needed for each shader program:
  4399. program.name = id;
  4400. // Lazy cache results of
  4401. // glGetProgramiv(GL_ACTIVE_UNIFORM_MAX_LENGTH/GL_ACTIVE_ATTRIBUTE_MAX_LENGTH/GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH)
  4402. program.maxUniformLength = program.maxAttributeLength = program.maxUniformBlockNameLength = 0;
  4403. program.uniformIdCounter = 1;
  4404. GL.programs[id] = program;
  4405. return id;
  4406. };
  4407. var _emscripten_glCreateProgram = _glCreateProgram;
  4408. /** @suppress {duplicate } */
  4409. var _glCreateShader = (shaderType) => {
  4410. var id = GL.getNewId(GL.shaders);
  4411. GL.shaders[id] = GLctx.createShader(shaderType);
  4412. return id;
  4413. };
  4414. var _emscripten_glCreateShader = _glCreateShader;
  4415. /** @suppress {duplicate } */
  4416. var _glCullFace = (x0) => GLctx.cullFace(x0);
  4417. var _emscripten_glCullFace = _glCullFace;
  4418. /** @suppress {duplicate } */
  4419. var _glDeleteBuffers = (n, buffers) => {
  4420. for (var i = 0; i < n; i++) {
  4421. var id = HEAP32[(((buffers)+(i*4))>>2)];
  4422. var buffer = GL.buffers[id];
  4423. // From spec: "glDeleteBuffers silently ignores 0's and names that do not
  4424. // correspond to existing buffer objects."
  4425. if (!buffer) continue;
  4426. GLctx.deleteBuffer(buffer);
  4427. buffer.name = 0;
  4428. GL.buffers[id] = null;
  4429. }
  4430. };
  4431. var _emscripten_glDeleteBuffers = _glDeleteBuffers;
  4432. /** @suppress {duplicate } */
  4433. var _glDeleteFramebuffers = (n, framebuffers) => {
  4434. for (var i = 0; i < n; ++i) {
  4435. var id = HEAP32[(((framebuffers)+(i*4))>>2)];
  4436. var framebuffer = GL.framebuffers[id];
  4437. if (!framebuffer) continue; // GL spec: "glDeleteFramebuffers silently ignores 0s and names that do not correspond to existing framebuffer objects".
  4438. GLctx.deleteFramebuffer(framebuffer);
  4439. framebuffer.name = 0;
  4440. GL.framebuffers[id] = null;
  4441. }
  4442. };
  4443. var _emscripten_glDeleteFramebuffers = _glDeleteFramebuffers;
  4444. /** @suppress {duplicate } */
  4445. var _glDeleteProgram = (id) => {
  4446. if (!id) return;
  4447. var program = GL.programs[id];
  4448. if (!program) {
  4449. // glDeleteProgram actually signals an error when deleting a nonexisting
  4450. // object, unlike some other GL delete functions.
  4451. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  4452. return;
  4453. }
  4454. GLctx.deleteProgram(program);
  4455. program.name = 0;
  4456. GL.programs[id] = null;
  4457. };
  4458. var _emscripten_glDeleteProgram = _glDeleteProgram;
  4459. /** @suppress {duplicate } */
  4460. var _glDeleteQueriesEXT = (n, ids) => {
  4461. for (var i = 0; i < n; i++) {
  4462. var id = HEAP32[(((ids)+(i*4))>>2)];
  4463. var query = GL.queries[id];
  4464. if (!query) continue; // GL spec: "unused names in ids are ignored, as is the name zero."
  4465. GLctx.disjointTimerQueryExt['deleteQueryEXT'](query);
  4466. GL.queries[id] = null;
  4467. }
  4468. };
  4469. var _emscripten_glDeleteQueriesEXT = _glDeleteQueriesEXT;
  4470. /** @suppress {duplicate } */
  4471. var _glDeleteRenderbuffers = (n, renderbuffers) => {
  4472. for (var i = 0; i < n; i++) {
  4473. var id = HEAP32[(((renderbuffers)+(i*4))>>2)];
  4474. var renderbuffer = GL.renderbuffers[id];
  4475. if (!renderbuffer) continue; // GL spec: "glDeleteRenderbuffers silently ignores 0s and names that do not correspond to existing renderbuffer objects".
  4476. GLctx.deleteRenderbuffer(renderbuffer);
  4477. renderbuffer.name = 0;
  4478. GL.renderbuffers[id] = null;
  4479. }
  4480. };
  4481. var _emscripten_glDeleteRenderbuffers = _glDeleteRenderbuffers;
  4482. /** @suppress {duplicate } */
  4483. var _glDeleteShader = (id) => {
  4484. if (!id) return;
  4485. var shader = GL.shaders[id];
  4486. if (!shader) {
  4487. // glDeleteShader actually signals an error when deleting a nonexisting
  4488. // object, unlike some other GL delete functions.
  4489. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  4490. return;
  4491. }
  4492. GLctx.deleteShader(shader);
  4493. GL.shaders[id] = null;
  4494. };
  4495. var _emscripten_glDeleteShader = _glDeleteShader;
  4496. /** @suppress {duplicate } */
  4497. var _glDeleteTextures = (n, textures) => {
  4498. for (var i = 0; i < n; i++) {
  4499. var id = HEAP32[(((textures)+(i*4))>>2)];
  4500. var texture = GL.textures[id];
  4501. // GL spec: "glDeleteTextures silently ignores 0s and names that do not
  4502. // correspond to existing textures".
  4503. if (!texture) continue;
  4504. GLctx.deleteTexture(texture);
  4505. texture.name = 0;
  4506. GL.textures[id] = null;
  4507. }
  4508. };
  4509. var _emscripten_glDeleteTextures = _glDeleteTextures;
  4510. /** @suppress {duplicate } */
  4511. var _glDeleteVertexArrays = (n, vaos) => {
  4512. for (var i = 0; i < n; i++) {
  4513. var id = HEAP32[(((vaos)+(i*4))>>2)];
  4514. GLctx.deleteVertexArray(GL.vaos[id]);
  4515. GL.vaos[id] = null;
  4516. }
  4517. };
  4518. /** @suppress {duplicate } */
  4519. var _glDeleteVertexArraysOES = _glDeleteVertexArrays;
  4520. var _emscripten_glDeleteVertexArraysOES = _glDeleteVertexArraysOES;
  4521. /** @suppress {duplicate } */
  4522. var _glDepthFunc = (x0) => GLctx.depthFunc(x0);
  4523. var _emscripten_glDepthFunc = _glDepthFunc;
  4524. /** @suppress {duplicate } */
  4525. var _glDepthMask = (flag) => {
  4526. GLctx.depthMask(!!flag);
  4527. };
  4528. var _emscripten_glDepthMask = _glDepthMask;
  4529. /** @suppress {duplicate } */
  4530. var _glDepthRangef = (x0, x1) => GLctx.depthRange(x0, x1);
  4531. var _emscripten_glDepthRangef = _glDepthRangef;
  4532. /** @suppress {duplicate } */
  4533. var _glDetachShader = (program, shader) => {
  4534. GLctx.detachShader(GL.programs[program], GL.shaders[shader]);
  4535. };
  4536. var _emscripten_glDetachShader = _glDetachShader;
  4537. /** @suppress {duplicate } */
  4538. var _glDisable = (x0) => GLctx.disable(x0);
  4539. var _emscripten_glDisable = _glDisable;
  4540. /** @suppress {duplicate } */
  4541. var _glDisableVertexAttribArray = (index) => {
  4542. GLctx.disableVertexAttribArray(index);
  4543. };
  4544. var _emscripten_glDisableVertexAttribArray = _glDisableVertexAttribArray;
  4545. /** @suppress {duplicate } */
  4546. var _glDrawArrays = (mode, first, count) => {
  4547. GLctx.drawArrays(mode, first, count);
  4548. };
  4549. var _emscripten_glDrawArrays = _glDrawArrays;
  4550. /** @suppress {duplicate } */
  4551. var _glDrawArraysInstanced = (mode, first, count, primcount) => {
  4552. GLctx.drawArraysInstanced(mode, first, count, primcount);
  4553. };
  4554. /** @suppress {duplicate } */
  4555. var _glDrawArraysInstancedANGLE = _glDrawArraysInstanced;
  4556. var _emscripten_glDrawArraysInstancedANGLE = _glDrawArraysInstancedANGLE;
  4557. var tempFixedLengthArray = [];
  4558. /** @suppress {duplicate } */
  4559. var _glDrawBuffers = (n, bufs) => {
  4560. var bufArray = tempFixedLengthArray[n];
  4561. for (var i = 0; i < n; i++) {
  4562. bufArray[i] = HEAP32[(((bufs)+(i*4))>>2)];
  4563. }
  4564. GLctx.drawBuffers(bufArray);
  4565. };
  4566. /** @suppress {duplicate } */
  4567. var _glDrawBuffersWEBGL = _glDrawBuffers;
  4568. var _emscripten_glDrawBuffersWEBGL = _glDrawBuffersWEBGL;
  4569. /** @suppress {duplicate } */
  4570. var _glDrawElements = (mode, count, type, indices) => {
  4571. GLctx.drawElements(mode, count, type, indices);
  4572. };
  4573. var _emscripten_glDrawElements = _glDrawElements;
  4574. /** @suppress {duplicate } */
  4575. var _glDrawElementsInstanced = (mode, count, type, indices, primcount) => {
  4576. GLctx.drawElementsInstanced(mode, count, type, indices, primcount);
  4577. };
  4578. /** @suppress {duplicate } */
  4579. var _glDrawElementsInstancedANGLE = _glDrawElementsInstanced;
  4580. var _emscripten_glDrawElementsInstancedANGLE = _glDrawElementsInstancedANGLE;
  4581. /** @suppress {duplicate } */
  4582. var _glEnable = (x0) => GLctx.enable(x0);
  4583. var _emscripten_glEnable = _glEnable;
  4584. /** @suppress {duplicate } */
  4585. var _glEnableVertexAttribArray = (index) => {
  4586. GLctx.enableVertexAttribArray(index);
  4587. };
  4588. var _emscripten_glEnableVertexAttribArray = _glEnableVertexAttribArray;
  4589. /** @suppress {duplicate } */
  4590. var _glEndQueryEXT = (target) => {
  4591. GLctx.disjointTimerQueryExt['endQueryEXT'](target);
  4592. };
  4593. var _emscripten_glEndQueryEXT = _glEndQueryEXT;
  4594. /** @suppress {duplicate } */
  4595. var _glFinish = () => GLctx.finish();
  4596. var _emscripten_glFinish = _glFinish;
  4597. /** @suppress {duplicate } */
  4598. var _glFlush = () => GLctx.flush();
  4599. var _emscripten_glFlush = _glFlush;
  4600. /** @suppress {duplicate } */
  4601. var _glFramebufferRenderbuffer = (target, attachment, renderbuffertarget, renderbuffer) => {
  4602. GLctx.framebufferRenderbuffer(target, attachment, renderbuffertarget,
  4603. GL.renderbuffers[renderbuffer]);
  4604. };
  4605. var _emscripten_glFramebufferRenderbuffer = _glFramebufferRenderbuffer;
  4606. /** @suppress {duplicate } */
  4607. var _glFramebufferTexture2D = (target, attachment, textarget, texture, level) => {
  4608. GLctx.framebufferTexture2D(target, attachment, textarget,
  4609. GL.textures[texture], level);
  4610. };
  4611. var _emscripten_glFramebufferTexture2D = _glFramebufferTexture2D;
  4612. /** @suppress {duplicate } */
  4613. var _glFrontFace = (x0) => GLctx.frontFace(x0);
  4614. var _emscripten_glFrontFace = _glFrontFace;
  4615. /** @suppress {duplicate } */
  4616. var _glGenBuffers = (n, buffers) => {
  4617. GL.genObject(n, buffers, 'createBuffer', GL.buffers
  4618. );
  4619. };
  4620. var _emscripten_glGenBuffers = _glGenBuffers;
  4621. /** @suppress {duplicate } */
  4622. var _glGenFramebuffers = (n, ids) => {
  4623. GL.genObject(n, ids, 'createFramebuffer', GL.framebuffers
  4624. );
  4625. };
  4626. var _emscripten_glGenFramebuffers = _glGenFramebuffers;
  4627. /** @suppress {duplicate } */
  4628. var _glGenQueriesEXT = (n, ids) => {
  4629. for (var i = 0; i < n; i++) {
  4630. var query = GLctx.disjointTimerQueryExt['createQueryEXT']();
  4631. if (!query) {
  4632. GL.recordError(0x502 /* GL_INVALID_OPERATION */);
  4633. while (i < n) HEAP32[(((ids)+(i++*4))>>2)] = 0;
  4634. return;
  4635. }
  4636. var id = GL.getNewId(GL.queries);
  4637. query.name = id;
  4638. GL.queries[id] = query;
  4639. HEAP32[(((ids)+(i*4))>>2)] = id;
  4640. }
  4641. };
  4642. var _emscripten_glGenQueriesEXT = _glGenQueriesEXT;
  4643. /** @suppress {duplicate } */
  4644. var _glGenRenderbuffers = (n, renderbuffers) => {
  4645. GL.genObject(n, renderbuffers, 'createRenderbuffer', GL.renderbuffers
  4646. );
  4647. };
  4648. var _emscripten_glGenRenderbuffers = _glGenRenderbuffers;
  4649. /** @suppress {duplicate } */
  4650. var _glGenTextures = (n, textures) => {
  4651. GL.genObject(n, textures, 'createTexture', GL.textures
  4652. );
  4653. };
  4654. var _emscripten_glGenTextures = _glGenTextures;
  4655. /** @suppress {duplicate } */
  4656. var _glGenVertexArrays = (n, arrays) => {
  4657. GL.genObject(n, arrays, 'createVertexArray', GL.vaos
  4658. );
  4659. };
  4660. /** @suppress {duplicate } */
  4661. var _glGenVertexArraysOES = _glGenVertexArrays;
  4662. var _emscripten_glGenVertexArraysOES = _glGenVertexArraysOES;
  4663. /** @suppress {duplicate } */
  4664. var _glGenerateMipmap = (x0) => GLctx.generateMipmap(x0);
  4665. var _emscripten_glGenerateMipmap = _glGenerateMipmap;
  4666. var __glGetActiveAttribOrUniform = (funcName, program, index, bufSize, length, size, type, name) => {
  4667. program = GL.programs[program];
  4668. var info = GLctx[funcName](program, index);
  4669. if (info) {
  4670. // If an error occurs, nothing will be written to length, size and type and name.
  4671. var numBytesWrittenExclNull = name && stringToUTF8(info.name, name, bufSize);
  4672. if (length) HEAP32[((length)>>2)] = numBytesWrittenExclNull;
  4673. if (size) HEAP32[((size)>>2)] = info.size;
  4674. if (type) HEAP32[((type)>>2)] = info.type;
  4675. }
  4676. };
  4677. /** @suppress {duplicate } */
  4678. var _glGetActiveAttrib = (program, index, bufSize, length, size, type, name) =>
  4679. __glGetActiveAttribOrUniform('getActiveAttrib', program, index, bufSize, length, size, type, name);
  4680. var _emscripten_glGetActiveAttrib = _glGetActiveAttrib;
  4681. /** @suppress {duplicate } */
  4682. var _glGetActiveUniform = (program, index, bufSize, length, size, type, name) =>
  4683. __glGetActiveAttribOrUniform('getActiveUniform', program, index, bufSize, length, size, type, name);
  4684. var _emscripten_glGetActiveUniform = _glGetActiveUniform;
  4685. /** @suppress {duplicate } */
  4686. var _glGetAttachedShaders = (program, maxCount, count, shaders) => {
  4687. var result = GLctx.getAttachedShaders(GL.programs[program]);
  4688. var len = result.length;
  4689. if (len > maxCount) {
  4690. len = maxCount;
  4691. }
  4692. HEAP32[((count)>>2)] = len;
  4693. for (var i = 0; i < len; ++i) {
  4694. var id = GL.shaders.indexOf(result[i]);
  4695. HEAP32[(((shaders)+(i*4))>>2)] = id;
  4696. }
  4697. };
  4698. var _emscripten_glGetAttachedShaders = _glGetAttachedShaders;
  4699. /** @suppress {duplicate } */
  4700. var _glGetAttribLocation = (program, name) =>
  4701. GLctx.getAttribLocation(GL.programs[program], UTF8ToString(name));
  4702. var _emscripten_glGetAttribLocation = _glGetAttribLocation;
  4703. var readI53FromI64 = (ptr) => {
  4704. return HEAPU32[((ptr)>>2)] + HEAP32[(((ptr)+(4))>>2)] * 4294967296;
  4705. };
  4706. var readI53FromU64 = (ptr) => {
  4707. return HEAPU32[((ptr)>>2)] + HEAPU32[(((ptr)+(4))>>2)] * 4294967296;
  4708. };
  4709. var writeI53ToI64 = (ptr, num) => {
  4710. HEAPU32[((ptr)>>2)] = num;
  4711. var lower = HEAPU32[((ptr)>>2)];
  4712. HEAPU32[(((ptr)+(4))>>2)] = (num - lower)/4294967296;
  4713. var deserialized = (num >= 0) ? readI53FromU64(ptr) : readI53FromI64(ptr);
  4714. var offset = ((ptr)>>2);
  4715. 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!`);
  4716. };
  4717. var emscriptenWebGLGet = (name_, p, type) => {
  4718. // Guard against user passing a null pointer.
  4719. // Note that GLES2 spec does not say anything about how passing a null
  4720. // pointer should be treated. Testing on desktop core GL 3, the application
  4721. // crashes on glGetIntegerv to a null pointer, but better to report an error
  4722. // instead of doing anything random.
  4723. if (!p) {
  4724. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  4725. return;
  4726. }
  4727. var ret = undefined;
  4728. switch (name_) { // Handle a few trivial GLES values
  4729. case 0x8DFA: // GL_SHADER_COMPILER
  4730. ret = 1;
  4731. break;
  4732. case 0x8DF8: // GL_SHADER_BINARY_FORMATS
  4733. if (type != 0 && type != 1) {
  4734. GL.recordError(0x500); // GL_INVALID_ENUM
  4735. }
  4736. // Do not write anything to the out pointer, since no binary formats are
  4737. // supported.
  4738. return;
  4739. case 0x8DF9: // GL_NUM_SHADER_BINARY_FORMATS
  4740. ret = 0;
  4741. break;
  4742. case 0x86A2: // GL_NUM_COMPRESSED_TEXTURE_FORMATS
  4743. // WebGL doesn't have GL_NUM_COMPRESSED_TEXTURE_FORMATS (it's obsolete
  4744. // since GL_COMPRESSED_TEXTURE_FORMATS returns a JS array that can be
  4745. // queried for length), so implement it ourselves to allow C++ GLES2
  4746. // code get the length.
  4747. var formats = GLctx.getParameter(0x86A3 /*GL_COMPRESSED_TEXTURE_FORMATS*/);
  4748. ret = formats ? formats.length : 0;
  4749. break;
  4750. }
  4751. if (ret === undefined) {
  4752. var result = GLctx.getParameter(name_);
  4753. switch (typeof result) {
  4754. case "number":
  4755. ret = result;
  4756. break;
  4757. case "boolean":
  4758. ret = result ? 1 : 0;
  4759. break;
  4760. case "string":
  4761. GL.recordError(0x500); // GL_INVALID_ENUM
  4762. return;
  4763. case "object":
  4764. if (result === null) {
  4765. // null is a valid result for some (e.g., which buffer is bound -
  4766. // perhaps nothing is bound), but otherwise can mean an invalid
  4767. // name_, which we need to report as an error
  4768. switch (name_) {
  4769. case 0x8894: // ARRAY_BUFFER_BINDING
  4770. case 0x8B8D: // CURRENT_PROGRAM
  4771. case 0x8895: // ELEMENT_ARRAY_BUFFER_BINDING
  4772. case 0x8CA6: // FRAMEBUFFER_BINDING or DRAW_FRAMEBUFFER_BINDING
  4773. case 0x8CA7: // RENDERBUFFER_BINDING
  4774. case 0x8069: // TEXTURE_BINDING_2D
  4775. case 0x85B5: // WebGL 2 GL_VERTEX_ARRAY_BINDING, or WebGL 1 extension OES_vertex_array_object GL_VERTEX_ARRAY_BINDING_OES
  4776. case 0x8514: { // TEXTURE_BINDING_CUBE_MAP
  4777. ret = 0;
  4778. break;
  4779. }
  4780. default: {
  4781. GL.recordError(0x500); // GL_INVALID_ENUM
  4782. return;
  4783. }
  4784. }
  4785. } else if (result instanceof Float32Array ||
  4786. result instanceof Uint32Array ||
  4787. result instanceof Int32Array ||
  4788. result instanceof Array) {
  4789. for (var i = 0; i < result.length; ++i) {
  4790. switch (type) {
  4791. case 0: HEAP32[(((p)+(i*4))>>2)] = result[i]; break;
  4792. case 2: HEAPF32[(((p)+(i*4))>>2)] = result[i]; break;
  4793. case 4: HEAP8[(p)+(i)] = result[i] ? 1 : 0; break;
  4794. }
  4795. }
  4796. return;
  4797. } else {
  4798. try {
  4799. ret = result.name | 0;
  4800. } catch(e) {
  4801. GL.recordError(0x500); // GL_INVALID_ENUM
  4802. err(`GL_INVALID_ENUM in glGet${type}v: Unknown object returned from WebGL getParameter(${name_})! (error: ${e})`);
  4803. return;
  4804. }
  4805. }
  4806. break;
  4807. default:
  4808. GL.recordError(0x500); // GL_INVALID_ENUM
  4809. err(`GL_INVALID_ENUM in glGet${type}v: Native code calling glGet${type}v(${name_}) and it returns ${result} of type ${typeof(result)}!`);
  4810. return;
  4811. }
  4812. }
  4813. switch (type) {
  4814. case 1: writeI53ToI64(p, ret); break;
  4815. case 0: HEAP32[((p)>>2)] = ret; break;
  4816. case 2: HEAPF32[((p)>>2)] = ret; break;
  4817. case 4: HEAP8[p] = ret ? 1 : 0; break;
  4818. }
  4819. };
  4820. /** @suppress {duplicate } */
  4821. var _glGetBooleanv = (name_, p) => emscriptenWebGLGet(name_, p, 4);
  4822. var _emscripten_glGetBooleanv = _glGetBooleanv;
  4823. /** @suppress {duplicate } */
  4824. var _glGetBufferParameteriv = (target, value, data) => {
  4825. if (!data) {
  4826. // GLES2 specification does not specify how to behave if data is a null
  4827. // pointer. Since calling this function does not make sense if data ==
  4828. // null, issue a GL error to notify user about it.
  4829. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  4830. return;
  4831. }
  4832. HEAP32[((data)>>2)] = GLctx.getBufferParameter(target, value);
  4833. };
  4834. var _emscripten_glGetBufferParameteriv = _glGetBufferParameteriv;
  4835. /** @suppress {duplicate } */
  4836. var _glGetError = () => {
  4837. var error = GLctx.getError() || GL.lastError;
  4838. GL.lastError = 0/*GL_NO_ERROR*/;
  4839. return error;
  4840. };
  4841. var _emscripten_glGetError = _glGetError;
  4842. /** @suppress {duplicate } */
  4843. var _glGetFloatv = (name_, p) => emscriptenWebGLGet(name_, p, 2);
  4844. var _emscripten_glGetFloatv = _glGetFloatv;
  4845. /** @suppress {duplicate } */
  4846. var _glGetFramebufferAttachmentParameteriv = (target, attachment, pname, params) => {
  4847. var result = GLctx.getFramebufferAttachmentParameter(target, attachment, pname);
  4848. if (result instanceof WebGLRenderbuffer ||
  4849. result instanceof WebGLTexture) {
  4850. result = result.name | 0;
  4851. }
  4852. HEAP32[((params)>>2)] = result;
  4853. };
  4854. var _emscripten_glGetFramebufferAttachmentParameteriv = _glGetFramebufferAttachmentParameteriv;
  4855. /** @suppress {duplicate } */
  4856. var _glGetIntegerv = (name_, p) => emscriptenWebGLGet(name_, p, 0);
  4857. var _emscripten_glGetIntegerv = _glGetIntegerv;
  4858. /** @suppress {duplicate } */
  4859. var _glGetProgramInfoLog = (program, maxLength, length, infoLog) => {
  4860. var log = GLctx.getProgramInfoLog(GL.programs[program]);
  4861. if (log === null) log = '(unknown error)';
  4862. var numBytesWrittenExclNull = (maxLength > 0 && infoLog) ? stringToUTF8(log, infoLog, maxLength) : 0;
  4863. if (length) HEAP32[((length)>>2)] = numBytesWrittenExclNull;
  4864. };
  4865. var _emscripten_glGetProgramInfoLog = _glGetProgramInfoLog;
  4866. /** @suppress {duplicate } */
  4867. var _glGetProgramiv = (program, pname, p) => {
  4868. if (!p) {
  4869. // GLES2 specification does not specify how to behave if p is a null
  4870. // pointer. Since calling this function does not make sense if p == null,
  4871. // issue a GL error to notify user about it.
  4872. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  4873. return;
  4874. }
  4875. if (program >= GL.counter) {
  4876. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  4877. return;
  4878. }
  4879. program = GL.programs[program];
  4880. if (pname == 0x8B84) { // GL_INFO_LOG_LENGTH
  4881. var log = GLctx.getProgramInfoLog(program);
  4882. if (log === null) log = '(unknown error)';
  4883. HEAP32[((p)>>2)] = log.length + 1;
  4884. } else if (pname == 0x8B87 /* GL_ACTIVE_UNIFORM_MAX_LENGTH */) {
  4885. if (!program.maxUniformLength) {
  4886. var numActiveUniforms = GLctx.getProgramParameter(program, 0x8B86/*GL_ACTIVE_UNIFORMS*/);
  4887. for (var i = 0; i < numActiveUniforms; ++i) {
  4888. program.maxUniformLength = Math.max(program.maxUniformLength, GLctx.getActiveUniform(program, i).name.length+1);
  4889. }
  4890. }
  4891. HEAP32[((p)>>2)] = program.maxUniformLength;
  4892. } else if (pname == 0x8B8A /* GL_ACTIVE_ATTRIBUTE_MAX_LENGTH */) {
  4893. if (!program.maxAttributeLength) {
  4894. var numActiveAttributes = GLctx.getProgramParameter(program, 0x8B89/*GL_ACTIVE_ATTRIBUTES*/);
  4895. for (var i = 0; i < numActiveAttributes; ++i) {
  4896. program.maxAttributeLength = Math.max(program.maxAttributeLength, GLctx.getActiveAttrib(program, i).name.length+1);
  4897. }
  4898. }
  4899. HEAP32[((p)>>2)] = program.maxAttributeLength;
  4900. } else if (pname == 0x8A35 /* GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH */) {
  4901. if (!program.maxUniformBlockNameLength) {
  4902. var numActiveUniformBlocks = GLctx.getProgramParameter(program, 0x8A36/*GL_ACTIVE_UNIFORM_BLOCKS*/);
  4903. for (var i = 0; i < numActiveUniformBlocks; ++i) {
  4904. program.maxUniformBlockNameLength = Math.max(program.maxUniformBlockNameLength, GLctx.getActiveUniformBlockName(program, i).length+1);
  4905. }
  4906. }
  4907. HEAP32[((p)>>2)] = program.maxUniformBlockNameLength;
  4908. } else {
  4909. HEAP32[((p)>>2)] = GLctx.getProgramParameter(program, pname);
  4910. }
  4911. };
  4912. var _emscripten_glGetProgramiv = _glGetProgramiv;
  4913. /** @suppress {duplicate } */
  4914. var _glGetQueryObjecti64vEXT = (id, pname, params) => {
  4915. if (!params) {
  4916. // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
  4917. // if p == null, issue a GL error to notify user about it.
  4918. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  4919. return;
  4920. }
  4921. var query = GL.queries[id];
  4922. var param;
  4923. {
  4924. param = GLctx.disjointTimerQueryExt['getQueryObjectEXT'](query, pname);
  4925. }
  4926. var ret;
  4927. if (typeof param == 'boolean') {
  4928. ret = param ? 1 : 0;
  4929. } else {
  4930. ret = param;
  4931. }
  4932. writeI53ToI64(params, ret);
  4933. };
  4934. var _emscripten_glGetQueryObjecti64vEXT = _glGetQueryObjecti64vEXT;
  4935. /** @suppress {duplicate } */
  4936. var _glGetQueryObjectivEXT = (id, pname, params) => {
  4937. if (!params) {
  4938. // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
  4939. // if p == null, issue a GL error to notify user about it.
  4940. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  4941. return;
  4942. }
  4943. var query = GL.queries[id];
  4944. var param = GLctx.disjointTimerQueryExt['getQueryObjectEXT'](query, pname);
  4945. var ret;
  4946. if (typeof param == 'boolean') {
  4947. ret = param ? 1 : 0;
  4948. } else {
  4949. ret = param;
  4950. }
  4951. HEAP32[((params)>>2)] = ret;
  4952. };
  4953. var _emscripten_glGetQueryObjectivEXT = _glGetQueryObjectivEXT;
  4954. /** @suppress {duplicate } */
  4955. var _glGetQueryObjectui64vEXT = _glGetQueryObjecti64vEXT;
  4956. var _emscripten_glGetQueryObjectui64vEXT = _glGetQueryObjectui64vEXT;
  4957. /** @suppress {duplicate } */
  4958. var _glGetQueryObjectuivEXT = _glGetQueryObjectivEXT;
  4959. var _emscripten_glGetQueryObjectuivEXT = _glGetQueryObjectuivEXT;
  4960. /** @suppress {duplicate } */
  4961. var _glGetQueryivEXT = (target, pname, params) => {
  4962. if (!params) {
  4963. // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
  4964. // if p == null, issue a GL error to notify user about it.
  4965. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  4966. return;
  4967. }
  4968. HEAP32[((params)>>2)] = GLctx.disjointTimerQueryExt['getQueryEXT'](target, pname);
  4969. };
  4970. var _emscripten_glGetQueryivEXT = _glGetQueryivEXT;
  4971. /** @suppress {duplicate } */
  4972. var _glGetRenderbufferParameteriv = (target, pname, params) => {
  4973. if (!params) {
  4974. // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
  4975. // if params == null, issue a GL error to notify user about it.
  4976. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  4977. return;
  4978. }
  4979. HEAP32[((params)>>2)] = GLctx.getRenderbufferParameter(target, pname);
  4980. };
  4981. var _emscripten_glGetRenderbufferParameteriv = _glGetRenderbufferParameteriv;
  4982. /** @suppress {duplicate } */
  4983. var _glGetShaderInfoLog = (shader, maxLength, length, infoLog) => {
  4984. var log = GLctx.getShaderInfoLog(GL.shaders[shader]);
  4985. if (log === null) log = '(unknown error)';
  4986. var numBytesWrittenExclNull = (maxLength > 0 && infoLog) ? stringToUTF8(log, infoLog, maxLength) : 0;
  4987. if (length) HEAP32[((length)>>2)] = numBytesWrittenExclNull;
  4988. };
  4989. var _emscripten_glGetShaderInfoLog = _glGetShaderInfoLog;
  4990. /** @suppress {duplicate } */
  4991. var _glGetShaderPrecisionFormat = (shaderType, precisionType, range, precision) => {
  4992. var result = GLctx.getShaderPrecisionFormat(shaderType, precisionType);
  4993. HEAP32[((range)>>2)] = result.rangeMin;
  4994. HEAP32[(((range)+(4))>>2)] = result.rangeMax;
  4995. HEAP32[((precision)>>2)] = result.precision;
  4996. };
  4997. var _emscripten_glGetShaderPrecisionFormat = _glGetShaderPrecisionFormat;
  4998. /** @suppress {duplicate } */
  4999. var _glGetShaderSource = (shader, bufSize, length, source) => {
  5000. var result = GLctx.getShaderSource(GL.shaders[shader]);
  5001. if (!result) return; // If an error occurs, nothing will be written to length or source.
  5002. var numBytesWrittenExclNull = (bufSize > 0 && source) ? stringToUTF8(result, source, bufSize) : 0;
  5003. if (length) HEAP32[((length)>>2)] = numBytesWrittenExclNull;
  5004. };
  5005. var _emscripten_glGetShaderSource = _glGetShaderSource;
  5006. /** @suppress {duplicate } */
  5007. var _glGetShaderiv = (shader, pname, p) => {
  5008. if (!p) {
  5009. // GLES2 specification does not specify how to behave if p is a null
  5010. // pointer. Since calling this function does not make sense if p == null,
  5011. // issue a GL error to notify user about it.
  5012. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  5013. return;
  5014. }
  5015. if (pname == 0x8B84) { // GL_INFO_LOG_LENGTH
  5016. var log = GLctx.getShaderInfoLog(GL.shaders[shader]);
  5017. if (log === null) log = '(unknown error)';
  5018. // The GLES2 specification says that if the shader has an empty info log,
  5019. // a value of 0 is returned. Otherwise the log has a null char appended.
  5020. // (An empty string is falsey, so we can just check that instead of
  5021. // looking at log.length.)
  5022. var logLength = log ? log.length + 1 : 0;
  5023. HEAP32[((p)>>2)] = logLength;
  5024. } else if (pname == 0x8B88) { // GL_SHADER_SOURCE_LENGTH
  5025. var source = GLctx.getShaderSource(GL.shaders[shader]);
  5026. // source may be a null, or the empty string, both of which are falsey
  5027. // values that we report a 0 length for.
  5028. var sourceLength = source ? source.length + 1 : 0;
  5029. HEAP32[((p)>>2)] = sourceLength;
  5030. } else {
  5031. HEAP32[((p)>>2)] = GLctx.getShaderParameter(GL.shaders[shader], pname);
  5032. }
  5033. };
  5034. var _emscripten_glGetShaderiv = _glGetShaderiv;
  5035. var stringToNewUTF8 = (str) => {
  5036. var size = lengthBytesUTF8(str) + 1;
  5037. var ret = _malloc(size);
  5038. if (ret) stringToUTF8(str, ret, size);
  5039. return ret;
  5040. };
  5041. var webglGetExtensions = () => {
  5042. var exts = getEmscriptenSupportedExtensions(GLctx);
  5043. exts = exts.concat(exts.map((e) => "GL_" + e));
  5044. return exts;
  5045. };
  5046. /** @suppress {duplicate } */
  5047. var _glGetString = (name_) => {
  5048. var ret = GL.stringCache[name_];
  5049. if (!ret) {
  5050. switch (name_) {
  5051. case 0x1F03 /* GL_EXTENSIONS */:
  5052. ret = stringToNewUTF8(webglGetExtensions().join(' '));
  5053. break;
  5054. case 0x1F00 /* GL_VENDOR */:
  5055. case 0x1F01 /* GL_RENDERER */:
  5056. case 0x9245 /* UNMASKED_VENDOR_WEBGL */:
  5057. case 0x9246 /* UNMASKED_RENDERER_WEBGL */:
  5058. var s = GLctx.getParameter(name_);
  5059. if (!s) {
  5060. GL.recordError(0x500/*GL_INVALID_ENUM*/);
  5061. }
  5062. ret = s ? stringToNewUTF8(s) : 0;
  5063. break;
  5064. case 0x1F02 /* GL_VERSION */:
  5065. var webGLVersion = GLctx.getParameter(0x1F02 /*GL_VERSION*/);
  5066. // return GLES version string corresponding to the version of the WebGL context
  5067. var glVersion = `OpenGL ES 2.0 (${webGLVersion})`;
  5068. ret = stringToNewUTF8(glVersion);
  5069. break;
  5070. case 0x8B8C /* GL_SHADING_LANGUAGE_VERSION */:
  5071. var glslVersion = GLctx.getParameter(0x8B8C /*GL_SHADING_LANGUAGE_VERSION*/);
  5072. // extract the version number 'N.M' from the string 'WebGL GLSL ES N.M ...'
  5073. var ver_re = /^WebGL GLSL ES ([0-9]\.[0-9][0-9]?)(?:$| .*)/;
  5074. var ver_num = glslVersion.match(ver_re);
  5075. if (ver_num !== null) {
  5076. if (ver_num[1].length == 3) ver_num[1] = ver_num[1] + '0'; // ensure minor version has 2 digits
  5077. glslVersion = `OpenGL ES GLSL ES ${ver_num[1]} (${glslVersion})`;
  5078. }
  5079. ret = stringToNewUTF8(glslVersion);
  5080. break;
  5081. default:
  5082. GL.recordError(0x500/*GL_INVALID_ENUM*/);
  5083. // fall through
  5084. }
  5085. GL.stringCache[name_] = ret;
  5086. }
  5087. return ret;
  5088. };
  5089. var _emscripten_glGetString = _glGetString;
  5090. /** @suppress {duplicate } */
  5091. var _glGetTexParameterfv = (target, pname, params) => {
  5092. if (!params) {
  5093. // GLES2 specification does not specify how to behave if params is a null
  5094. // pointer. Since calling this function does not make sense if p == null,
  5095. // issue a GL error to notify user about it.
  5096. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  5097. return;
  5098. }
  5099. HEAPF32[((params)>>2)] = GLctx.getTexParameter(target, pname);
  5100. };
  5101. var _emscripten_glGetTexParameterfv = _glGetTexParameterfv;
  5102. /** @suppress {duplicate } */
  5103. var _glGetTexParameteriv = (target, pname, params) => {
  5104. if (!params) {
  5105. // GLES2 specification does not specify how to behave if params is a null
  5106. // pointer. Since calling this function does not make sense if p == null,
  5107. // issue a GL error to notify user about it.
  5108. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  5109. return;
  5110. }
  5111. HEAP32[((params)>>2)] = GLctx.getTexParameter(target, pname);
  5112. };
  5113. var _emscripten_glGetTexParameteriv = _glGetTexParameteriv;
  5114. /** @suppress {checkTypes} */
  5115. var jstoi_q = (str) => parseInt(str);
  5116. /** @noinline */
  5117. var webglGetLeftBracePos = (name) => name.slice(-1) == ']' && name.lastIndexOf('[');
  5118. var webglPrepareUniformLocationsBeforeFirstUse = (program) => {
  5119. var uniformLocsById = program.uniformLocsById, // Maps GLuint -> WebGLUniformLocation
  5120. uniformSizeAndIdsByName = program.uniformSizeAndIdsByName, // Maps name -> [uniform array length, GLuint]
  5121. i, j;
  5122. // On the first time invocation of glGetUniformLocation on this shader program:
  5123. // initialize cache data structures and discover which uniforms are arrays.
  5124. if (!uniformLocsById) {
  5125. // maps GLint integer locations to WebGLUniformLocations
  5126. program.uniformLocsById = uniformLocsById = {};
  5127. // maps integer locations back to uniform name strings, so that we can lazily fetch uniform array locations
  5128. program.uniformArrayNamesById = {};
  5129. var numActiveUniforms = GLctx.getProgramParameter(program, 0x8B86/*GL_ACTIVE_UNIFORMS*/);
  5130. for (i = 0; i < numActiveUniforms; ++i) {
  5131. var u = GLctx.getActiveUniform(program, i);
  5132. var nm = u.name;
  5133. var sz = u.size;
  5134. var lb = webglGetLeftBracePos(nm);
  5135. var arrayName = lb > 0 ? nm.slice(0, lb) : nm;
  5136. // Assign a new location.
  5137. var id = program.uniformIdCounter;
  5138. program.uniformIdCounter += sz;
  5139. // Eagerly get the location of the uniformArray[0] base element.
  5140. // The remaining indices >0 will be left for lazy evaluation to
  5141. // improve performance. Those may never be needed to fetch, if the
  5142. // application fills arrays always in full starting from the first
  5143. // element of the array.
  5144. uniformSizeAndIdsByName[arrayName] = [sz, id];
  5145. // Store placeholder integers in place that highlight that these
  5146. // >0 index locations are array indices pending population.
  5147. for (j = 0; j < sz; ++j) {
  5148. uniformLocsById[id] = j;
  5149. program.uniformArrayNamesById[id++] = arrayName;
  5150. }
  5151. }
  5152. }
  5153. };
  5154. /** @suppress {duplicate } */
  5155. var _glGetUniformLocation = (program, name) => {
  5156. name = UTF8ToString(name);
  5157. if (program = GL.programs[program]) {
  5158. webglPrepareUniformLocationsBeforeFirstUse(program);
  5159. var uniformLocsById = program.uniformLocsById; // Maps GLuint -> WebGLUniformLocation
  5160. var arrayIndex = 0;
  5161. var uniformBaseName = name;
  5162. // Invariant: when populating integer IDs for uniform locations, we must
  5163. // maintain the precondition that arrays reside in contiguous addresses,
  5164. // i.e. for a 'vec4 colors[10];', colors[4] must be at location
  5165. // colors[0]+4. However, user might call glGetUniformLocation(program,
  5166. // "colors") for an array, so we cannot discover based on the user input
  5167. // arguments whether the uniform we are dealing with is an array. The only
  5168. // way to discover which uniforms are arrays is to enumerate over all the
  5169. // active uniforms in the program.
  5170. var leftBrace = webglGetLeftBracePos(name);
  5171. // If user passed an array accessor "[index]", parse the array index off the accessor.
  5172. if (leftBrace > 0) {
  5173. 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.
  5174. uniformBaseName = name.slice(0, leftBrace);
  5175. }
  5176. // Have we cached the location of this uniform before?
  5177. // A pair [array length, GLint of the uniform location]
  5178. var sizeAndId = program.uniformSizeAndIdsByName[uniformBaseName];
  5179. // If an uniform with this name exists, and if its index is within the
  5180. // array limits (if it's even an array), query the WebGLlocation, or
  5181. // return an existing cached location.
  5182. if (sizeAndId && arrayIndex < sizeAndId[0]) {
  5183. arrayIndex += sizeAndId[1]; // Add the base location of the uniform to the array index offset.
  5184. if ((uniformLocsById[arrayIndex] = uniformLocsById[arrayIndex] || GLctx.getUniformLocation(program, name))) {
  5185. return arrayIndex;
  5186. }
  5187. }
  5188. }
  5189. else {
  5190. // N.b. we are currently unable to distinguish between GL program IDs that
  5191. // never existed vs GL program IDs that have been deleted, so report
  5192. // GL_INVALID_VALUE in both cases.
  5193. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  5194. }
  5195. return -1;
  5196. };
  5197. var _emscripten_glGetUniformLocation = _glGetUniformLocation;
  5198. var webglGetUniformLocation = (location) => {
  5199. var p = GLctx.currentProgram;
  5200. if (p) {
  5201. var webglLoc = p.uniformLocsById[location];
  5202. // p.uniformLocsById[location] stores either an integer, or a
  5203. // WebGLUniformLocation.
  5204. // If an integer, we have not yet bound the location, so do it now. The
  5205. // integer value specifies the array index we should bind to.
  5206. if (typeof webglLoc == 'number') {
  5207. p.uniformLocsById[location] = webglLoc = GLctx.getUniformLocation(p, p.uniformArrayNamesById[location] + (webglLoc > 0 ? `[${webglLoc}]` : ''));
  5208. }
  5209. // Else an already cached WebGLUniformLocation, return it.
  5210. return webglLoc;
  5211. } else {
  5212. GL.recordError(0x502/*GL_INVALID_OPERATION*/);
  5213. }
  5214. };
  5215. /** @suppress{checkTypes} */
  5216. var emscriptenWebGLGetUniform = (program, location, params, type) => {
  5217. if (!params) {
  5218. // GLES2 specification does not specify how to behave if params is a null
  5219. // pointer. Since calling this function does not make sense if params ==
  5220. // null, issue a GL error to notify user about it.
  5221. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  5222. return;
  5223. }
  5224. program = GL.programs[program];
  5225. webglPrepareUniformLocationsBeforeFirstUse(program);
  5226. var data = GLctx.getUniform(program, webglGetUniformLocation(location));
  5227. if (typeof data == 'number' || typeof data == 'boolean') {
  5228. switch (type) {
  5229. case 0: HEAP32[((params)>>2)] = data; break;
  5230. case 2: HEAPF32[((params)>>2)] = data; break;
  5231. }
  5232. } else {
  5233. for (var i = 0; i < data.length; i++) {
  5234. switch (type) {
  5235. case 0: HEAP32[(((params)+(i*4))>>2)] = data[i]; break;
  5236. case 2: HEAPF32[(((params)+(i*4))>>2)] = data[i]; break;
  5237. }
  5238. }
  5239. }
  5240. };
  5241. /** @suppress {duplicate } */
  5242. var _glGetUniformfv = (program, location, params) => {
  5243. emscriptenWebGLGetUniform(program, location, params, 2);
  5244. };
  5245. var _emscripten_glGetUniformfv = _glGetUniformfv;
  5246. /** @suppress {duplicate } */
  5247. var _glGetUniformiv = (program, location, params) => {
  5248. emscriptenWebGLGetUniform(program, location, params, 0);
  5249. };
  5250. var _emscripten_glGetUniformiv = _glGetUniformiv;
  5251. /** @suppress {duplicate } */
  5252. var _glGetVertexAttribPointerv = (index, pname, pointer) => {
  5253. if (!pointer) {
  5254. // GLES2 specification does not specify how to behave if pointer is a null
  5255. // pointer. Since calling this function does not make sense if pointer ==
  5256. // null, issue a GL error to notify user about it.
  5257. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  5258. return;
  5259. }
  5260. HEAP32[((pointer)>>2)] = GLctx.getVertexAttribOffset(index, pname);
  5261. };
  5262. var _emscripten_glGetVertexAttribPointerv = _glGetVertexAttribPointerv;
  5263. /** @suppress{checkTypes} */
  5264. var emscriptenWebGLGetVertexAttrib = (index, pname, params, type) => {
  5265. if (!params) {
  5266. // GLES2 specification does not specify how to behave if params is a null
  5267. // pointer. Since calling this function does not make sense if params ==
  5268. // null, issue a GL error to notify user about it.
  5269. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  5270. return;
  5271. }
  5272. var data = GLctx.getVertexAttrib(index, pname);
  5273. if (pname == 0x889F/*VERTEX_ATTRIB_ARRAY_BUFFER_BINDING*/) {
  5274. HEAP32[((params)>>2)] = data && data["name"];
  5275. } else if (typeof data == 'number' || typeof data == 'boolean') {
  5276. switch (type) {
  5277. case 0: HEAP32[((params)>>2)] = data; break;
  5278. case 2: HEAPF32[((params)>>2)] = data; break;
  5279. case 5: HEAP32[((params)>>2)] = Math.fround(data); break;
  5280. }
  5281. } else {
  5282. for (var i = 0; i < data.length; i++) {
  5283. switch (type) {
  5284. case 0: HEAP32[(((params)+(i*4))>>2)] = data[i]; break;
  5285. case 2: HEAPF32[(((params)+(i*4))>>2)] = data[i]; break;
  5286. case 5: HEAP32[(((params)+(i*4))>>2)] = Math.fround(data[i]); break;
  5287. }
  5288. }
  5289. }
  5290. };
  5291. /** @suppress {duplicate } */
  5292. var _glGetVertexAttribfv = (index, pname, params) => {
  5293. // N.B. This function may only be called if the vertex attribute was
  5294. // specified using the function glVertexAttrib*f(), otherwise the results
  5295. // are undefined. (GLES3 spec 6.1.12)
  5296. emscriptenWebGLGetVertexAttrib(index, pname, params, 2);
  5297. };
  5298. var _emscripten_glGetVertexAttribfv = _glGetVertexAttribfv;
  5299. /** @suppress {duplicate } */
  5300. var _glGetVertexAttribiv = (index, pname, params) => {
  5301. // N.B. This function may only be called if the vertex attribute was
  5302. // specified using the function glVertexAttrib*f(), otherwise the results
  5303. // are undefined. (GLES3 spec 6.1.12)
  5304. emscriptenWebGLGetVertexAttrib(index, pname, params, 5);
  5305. };
  5306. var _emscripten_glGetVertexAttribiv = _glGetVertexAttribiv;
  5307. /** @suppress {duplicate } */
  5308. var _glHint = (x0, x1) => GLctx.hint(x0, x1);
  5309. var _emscripten_glHint = _glHint;
  5310. /** @suppress {duplicate } */
  5311. var _glIsBuffer = (buffer) => {
  5312. var b = GL.buffers[buffer];
  5313. if (!b) return 0;
  5314. return GLctx.isBuffer(b);
  5315. };
  5316. var _emscripten_glIsBuffer = _glIsBuffer;
  5317. /** @suppress {duplicate } */
  5318. var _glIsEnabled = (x0) => GLctx.isEnabled(x0);
  5319. var _emscripten_glIsEnabled = _glIsEnabled;
  5320. /** @suppress {duplicate } */
  5321. var _glIsFramebuffer = (framebuffer) => {
  5322. var fb = GL.framebuffers[framebuffer];
  5323. if (!fb) return 0;
  5324. return GLctx.isFramebuffer(fb);
  5325. };
  5326. var _emscripten_glIsFramebuffer = _glIsFramebuffer;
  5327. /** @suppress {duplicate } */
  5328. var _glIsProgram = (program) => {
  5329. program = GL.programs[program];
  5330. if (!program) return 0;
  5331. return GLctx.isProgram(program);
  5332. };
  5333. var _emscripten_glIsProgram = _glIsProgram;
  5334. /** @suppress {duplicate } */
  5335. var _glIsQueryEXT = (id) => {
  5336. var query = GL.queries[id];
  5337. if (!query) return 0;
  5338. return GLctx.disjointTimerQueryExt['isQueryEXT'](query);
  5339. };
  5340. var _emscripten_glIsQueryEXT = _glIsQueryEXT;
  5341. /** @suppress {duplicate } */
  5342. var _glIsRenderbuffer = (renderbuffer) => {
  5343. var rb = GL.renderbuffers[renderbuffer];
  5344. if (!rb) return 0;
  5345. return GLctx.isRenderbuffer(rb);
  5346. };
  5347. var _emscripten_glIsRenderbuffer = _glIsRenderbuffer;
  5348. /** @suppress {duplicate } */
  5349. var _glIsShader = (shader) => {
  5350. var s = GL.shaders[shader];
  5351. if (!s) return 0;
  5352. return GLctx.isShader(s);
  5353. };
  5354. var _emscripten_glIsShader = _glIsShader;
  5355. /** @suppress {duplicate } */
  5356. var _glIsTexture = (id) => {
  5357. var texture = GL.textures[id];
  5358. if (!texture) return 0;
  5359. return GLctx.isTexture(texture);
  5360. };
  5361. var _emscripten_glIsTexture = _glIsTexture;
  5362. /** @suppress {duplicate } */
  5363. var _glIsVertexArray = (array) => {
  5364. var vao = GL.vaos[array];
  5365. if (!vao) return 0;
  5366. return GLctx.isVertexArray(vao);
  5367. };
  5368. /** @suppress {duplicate } */
  5369. var _glIsVertexArrayOES = _glIsVertexArray;
  5370. var _emscripten_glIsVertexArrayOES = _glIsVertexArrayOES;
  5371. /** @suppress {duplicate } */
  5372. var _glLineWidth = (x0) => GLctx.lineWidth(x0);
  5373. var _emscripten_glLineWidth = _glLineWidth;
  5374. /** @suppress {duplicate } */
  5375. var _glLinkProgram = (program) => {
  5376. program = GL.programs[program];
  5377. GLctx.linkProgram(program);
  5378. // Invalidate earlier computed uniform->ID mappings, those have now become stale
  5379. program.uniformLocsById = 0; // Mark as null-like so that glGetUniformLocation() knows to populate this again.
  5380. program.uniformSizeAndIdsByName = {};
  5381. };
  5382. var _emscripten_glLinkProgram = _glLinkProgram;
  5383. /** @suppress {duplicate } */
  5384. var _glPixelStorei = (pname, param) => {
  5385. if (pname == 3317) {
  5386. GL.unpackAlignment = param;
  5387. } else if (pname == 3314) {
  5388. GL.unpackRowLength = param;
  5389. }
  5390. GLctx.pixelStorei(pname, param);
  5391. };
  5392. var _emscripten_glPixelStorei = _glPixelStorei;
  5393. /** @suppress {duplicate } */
  5394. var _glPolygonModeWEBGL = (face, mode) => {
  5395. GLctx.webglPolygonMode['polygonModeWEBGL'](face, mode);
  5396. };
  5397. var _emscripten_glPolygonModeWEBGL = _glPolygonModeWEBGL;
  5398. /** @suppress {duplicate } */
  5399. var _glPolygonOffset = (x0, x1) => GLctx.polygonOffset(x0, x1);
  5400. var _emscripten_glPolygonOffset = _glPolygonOffset;
  5401. /** @suppress {duplicate } */
  5402. var _glPolygonOffsetClampEXT = (factor, units, clamp) => {
  5403. GLctx.extPolygonOffsetClamp['polygonOffsetClampEXT'](factor, units, clamp);
  5404. };
  5405. var _emscripten_glPolygonOffsetClampEXT = _glPolygonOffsetClampEXT;
  5406. /** @suppress {duplicate } */
  5407. var _glQueryCounterEXT = (id, target) => {
  5408. GLctx.disjointTimerQueryExt['queryCounterEXT'](GL.queries[id], target);
  5409. };
  5410. var _emscripten_glQueryCounterEXT = _glQueryCounterEXT;
  5411. var computeUnpackAlignedImageSize = (width, height, sizePerPixel) => {
  5412. function roundedToNextMultipleOf(x, y) {
  5413. return (x + y - 1) & -y;
  5414. }
  5415. var plainRowSize = (GL.unpackRowLength || width) * sizePerPixel;
  5416. var alignedRowSize = roundedToNextMultipleOf(plainRowSize, GL.unpackAlignment);
  5417. return height * alignedRowSize;
  5418. };
  5419. var colorChannelsInGlTextureFormat = (format) => {
  5420. // Micro-optimizations for size: map format to size by subtracting smallest
  5421. // enum value (0x1902) from all values first. Also omit the most common
  5422. // size value (1) from the list, which is assumed by formats not on the
  5423. // list.
  5424. var colorChannels = {
  5425. // 0x1902 /* GL_DEPTH_COMPONENT */ - 0x1902: 1,
  5426. // 0x1906 /* GL_ALPHA */ - 0x1902: 1,
  5427. 5: 3,
  5428. 6: 4,
  5429. // 0x1909 /* GL_LUMINANCE */ - 0x1902: 1,
  5430. 8: 2,
  5431. 29502: 3,
  5432. 29504: 4,
  5433. };
  5434. return colorChannels[format - 0x1902]||1;
  5435. };
  5436. var heapObjectForWebGLType = (type) => {
  5437. // Micro-optimization for size: Subtract lowest GL enum number (0x1400/* GL_BYTE */) from type to compare
  5438. // smaller values for the heap, for shorter generated code size.
  5439. // Also the type HEAPU16 is not tested for explicitly, but any unrecognized type will return out HEAPU16.
  5440. // (since most types are HEAPU16)
  5441. type -= 0x1400;
  5442. if (type == 1) return HEAPU8;
  5443. if (type == 4) return HEAP32;
  5444. if (type == 6) return HEAPF32;
  5445. if (type == 5
  5446. || type == 28922
  5447. )
  5448. return HEAPU32;
  5449. return HEAPU16;
  5450. };
  5451. var toTypedArrayIndex = (pointer, heap) =>
  5452. pointer >>> (31 - Math.clz32(heap.BYTES_PER_ELEMENT));
  5453. var emscriptenWebGLGetTexPixelData = (type, format, width, height, pixels, internalFormat) => {
  5454. var heap = heapObjectForWebGLType(type);
  5455. var sizePerPixel = colorChannelsInGlTextureFormat(format) * heap.BYTES_PER_ELEMENT;
  5456. var bytes = computeUnpackAlignedImageSize(width, height, sizePerPixel);
  5457. return heap.subarray(toTypedArrayIndex(pixels, heap), toTypedArrayIndex(pixels + bytes, heap));
  5458. };
  5459. /** @suppress {duplicate } */
  5460. var _glReadPixels = (x, y, width, height, format, type, pixels) => {
  5461. var pixelData = emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, format);
  5462. if (!pixelData) {
  5463. GL.recordError(0x500/*GL_INVALID_ENUM*/);
  5464. return;
  5465. }
  5466. GLctx.readPixels(x, y, width, height, format, type, pixelData);
  5467. };
  5468. var _emscripten_glReadPixels = _glReadPixels;
  5469. /** @suppress {duplicate } */
  5470. var _glReleaseShaderCompiler = () => {
  5471. // NOP (as allowed by GLES 2.0 spec)
  5472. };
  5473. var _emscripten_glReleaseShaderCompiler = _glReleaseShaderCompiler;
  5474. /** @suppress {duplicate } */
  5475. var _glRenderbufferStorage = (x0, x1, x2, x3) => GLctx.renderbufferStorage(x0, x1, x2, x3);
  5476. var _emscripten_glRenderbufferStorage = _glRenderbufferStorage;
  5477. /** @suppress {duplicate } */
  5478. var _glSampleCoverage = (value, invert) => {
  5479. GLctx.sampleCoverage(value, !!invert);
  5480. };
  5481. var _emscripten_glSampleCoverage = _glSampleCoverage;
  5482. /** @suppress {duplicate } */
  5483. var _glScissor = (x0, x1, x2, x3) => GLctx.scissor(x0, x1, x2, x3);
  5484. var _emscripten_glScissor = _glScissor;
  5485. /** @suppress {duplicate } */
  5486. var _glShaderBinary = (count, shaders, binaryformat, binary, length) => {
  5487. GL.recordError(0x500/*GL_INVALID_ENUM*/);
  5488. };
  5489. var _emscripten_glShaderBinary = _glShaderBinary;
  5490. /** @suppress {duplicate } */
  5491. var _glShaderSource = (shader, count, string, length) => {
  5492. var source = GL.getSource(shader, count, string, length);
  5493. GLctx.shaderSource(GL.shaders[shader], source);
  5494. };
  5495. var _emscripten_glShaderSource = _glShaderSource;
  5496. /** @suppress {duplicate } */
  5497. var _glStencilFunc = (x0, x1, x2) => GLctx.stencilFunc(x0, x1, x2);
  5498. var _emscripten_glStencilFunc = _glStencilFunc;
  5499. /** @suppress {duplicate } */
  5500. var _glStencilFuncSeparate = (x0, x1, x2, x3) => GLctx.stencilFuncSeparate(x0, x1, x2, x3);
  5501. var _emscripten_glStencilFuncSeparate = _glStencilFuncSeparate;
  5502. /** @suppress {duplicate } */
  5503. var _glStencilMask = (x0) => GLctx.stencilMask(x0);
  5504. var _emscripten_glStencilMask = _glStencilMask;
  5505. /** @suppress {duplicate } */
  5506. var _glStencilMaskSeparate = (x0, x1) => GLctx.stencilMaskSeparate(x0, x1);
  5507. var _emscripten_glStencilMaskSeparate = _glStencilMaskSeparate;
  5508. /** @suppress {duplicate } */
  5509. var _glStencilOp = (x0, x1, x2) => GLctx.stencilOp(x0, x1, x2);
  5510. var _emscripten_glStencilOp = _glStencilOp;
  5511. /** @suppress {duplicate } */
  5512. var _glStencilOpSeparate = (x0, x1, x2, x3) => GLctx.stencilOpSeparate(x0, x1, x2, x3);
  5513. var _emscripten_glStencilOpSeparate = _glStencilOpSeparate;
  5514. /** @suppress {duplicate } */
  5515. var _glTexImage2D = (target, level, internalFormat, width, height, border, format, type, pixels) => {
  5516. var pixelData = pixels ? emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, internalFormat) : null;
  5517. GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, pixelData);
  5518. };
  5519. var _emscripten_glTexImage2D = _glTexImage2D;
  5520. /** @suppress {duplicate } */
  5521. var _glTexParameterf = (x0, x1, x2) => GLctx.texParameterf(x0, x1, x2);
  5522. var _emscripten_glTexParameterf = _glTexParameterf;
  5523. /** @suppress {duplicate } */
  5524. var _glTexParameterfv = (target, pname, params) => {
  5525. var param = HEAPF32[((params)>>2)];
  5526. GLctx.texParameterf(target, pname, param);
  5527. };
  5528. var _emscripten_glTexParameterfv = _glTexParameterfv;
  5529. /** @suppress {duplicate } */
  5530. var _glTexParameteri = (x0, x1, x2) => GLctx.texParameteri(x0, x1, x2);
  5531. var _emscripten_glTexParameteri = _glTexParameteri;
  5532. /** @suppress {duplicate } */
  5533. var _glTexParameteriv = (target, pname, params) => {
  5534. var param = HEAP32[((params)>>2)];
  5535. GLctx.texParameteri(target, pname, param);
  5536. };
  5537. var _emscripten_glTexParameteriv = _glTexParameteriv;
  5538. /** @suppress {duplicate } */
  5539. var _glTexSubImage2D = (target, level, xoffset, yoffset, width, height, format, type, pixels) => {
  5540. var pixelData = pixels ? emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, 0) : null;
  5541. GLctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixelData);
  5542. };
  5543. var _emscripten_glTexSubImage2D = _glTexSubImage2D;
  5544. /** @suppress {duplicate } */
  5545. var _glUniform1f = (location, v0) => {
  5546. GLctx.uniform1f(webglGetUniformLocation(location), v0);
  5547. };
  5548. var _emscripten_glUniform1f = _glUniform1f;
  5549. var miniTempWebGLFloatBuffers = [];
  5550. /** @suppress {duplicate } */
  5551. var _glUniform1fv = (location, count, value) => {
  5552. if (count <= 288) {
  5553. // avoid allocation when uploading few enough uniforms
  5554. var view = miniTempWebGLFloatBuffers[count];
  5555. for (var i = 0; i < count; ++i) {
  5556. view[i] = HEAPF32[(((value)+(4*i))>>2)];
  5557. }
  5558. } else
  5559. {
  5560. var view = HEAPF32.subarray((((value)>>2)), ((value+count*4)>>2));
  5561. }
  5562. GLctx.uniform1fv(webglGetUniformLocation(location), view);
  5563. };
  5564. var _emscripten_glUniform1fv = _glUniform1fv;
  5565. /** @suppress {duplicate } */
  5566. var _glUniform1i = (location, v0) => {
  5567. GLctx.uniform1i(webglGetUniformLocation(location), v0);
  5568. };
  5569. var _emscripten_glUniform1i = _glUniform1i;
  5570. var miniTempWebGLIntBuffers = [];
  5571. /** @suppress {duplicate } */
  5572. var _glUniform1iv = (location, count, value) => {
  5573. if (count <= 288) {
  5574. // avoid allocation when uploading few enough uniforms
  5575. var view = miniTempWebGLIntBuffers[count];
  5576. for (var i = 0; i < count; ++i) {
  5577. view[i] = HEAP32[(((value)+(4*i))>>2)];
  5578. }
  5579. } else
  5580. {
  5581. var view = HEAP32.subarray((((value)>>2)), ((value+count*4)>>2));
  5582. }
  5583. GLctx.uniform1iv(webglGetUniformLocation(location), view);
  5584. };
  5585. var _emscripten_glUniform1iv = _glUniform1iv;
  5586. /** @suppress {duplicate } */
  5587. var _glUniform2f = (location, v0, v1) => {
  5588. GLctx.uniform2f(webglGetUniformLocation(location), v0, v1);
  5589. };
  5590. var _emscripten_glUniform2f = _glUniform2f;
  5591. /** @suppress {duplicate } */
  5592. var _glUniform2fv = (location, count, value) => {
  5593. if (count <= 144) {
  5594. // avoid allocation when uploading few enough uniforms
  5595. count *= 2;
  5596. var view = miniTempWebGLFloatBuffers[count];
  5597. for (var i = 0; i < count; i += 2) {
  5598. view[i] = HEAPF32[(((value)+(4*i))>>2)];
  5599. view[i+1] = HEAPF32[(((value)+(4*i+4))>>2)];
  5600. }
  5601. } else
  5602. {
  5603. var view = HEAPF32.subarray((((value)>>2)), ((value+count*8)>>2));
  5604. }
  5605. GLctx.uniform2fv(webglGetUniformLocation(location), view);
  5606. };
  5607. var _emscripten_glUniform2fv = _glUniform2fv;
  5608. /** @suppress {duplicate } */
  5609. var _glUniform2i = (location, v0, v1) => {
  5610. GLctx.uniform2i(webglGetUniformLocation(location), v0, v1);
  5611. };
  5612. var _emscripten_glUniform2i = _glUniform2i;
  5613. /** @suppress {duplicate } */
  5614. var _glUniform2iv = (location, count, value) => {
  5615. if (count <= 144) {
  5616. // avoid allocation when uploading few enough uniforms
  5617. count *= 2;
  5618. var view = miniTempWebGLIntBuffers[count];
  5619. for (var i = 0; i < count; i += 2) {
  5620. view[i] = HEAP32[(((value)+(4*i))>>2)];
  5621. view[i+1] = HEAP32[(((value)+(4*i+4))>>2)];
  5622. }
  5623. } else
  5624. {
  5625. var view = HEAP32.subarray((((value)>>2)), ((value+count*8)>>2));
  5626. }
  5627. GLctx.uniform2iv(webglGetUniformLocation(location), view);
  5628. };
  5629. var _emscripten_glUniform2iv = _glUniform2iv;
  5630. /** @suppress {duplicate } */
  5631. var _glUniform3f = (location, v0, v1, v2) => {
  5632. GLctx.uniform3f(webglGetUniformLocation(location), v0, v1, v2);
  5633. };
  5634. var _emscripten_glUniform3f = _glUniform3f;
  5635. /** @suppress {duplicate } */
  5636. var _glUniform3fv = (location, count, value) => {
  5637. if (count <= 96) {
  5638. // avoid allocation when uploading few enough uniforms
  5639. count *= 3;
  5640. var view = miniTempWebGLFloatBuffers[count];
  5641. for (var i = 0; i < count; i += 3) {
  5642. view[i] = HEAPF32[(((value)+(4*i))>>2)];
  5643. view[i+1] = HEAPF32[(((value)+(4*i+4))>>2)];
  5644. view[i+2] = HEAPF32[(((value)+(4*i+8))>>2)];
  5645. }
  5646. } else
  5647. {
  5648. var view = HEAPF32.subarray((((value)>>2)), ((value+count*12)>>2));
  5649. }
  5650. GLctx.uniform3fv(webglGetUniformLocation(location), view);
  5651. };
  5652. var _emscripten_glUniform3fv = _glUniform3fv;
  5653. /** @suppress {duplicate } */
  5654. var _glUniform3i = (location, v0, v1, v2) => {
  5655. GLctx.uniform3i(webglGetUniformLocation(location), v0, v1, v2);
  5656. };
  5657. var _emscripten_glUniform3i = _glUniform3i;
  5658. /** @suppress {duplicate } */
  5659. var _glUniform3iv = (location, count, value) => {
  5660. if (count <= 96) {
  5661. // avoid allocation when uploading few enough uniforms
  5662. count *= 3;
  5663. var view = miniTempWebGLIntBuffers[count];
  5664. for (var i = 0; i < count; i += 3) {
  5665. view[i] = HEAP32[(((value)+(4*i))>>2)];
  5666. view[i+1] = HEAP32[(((value)+(4*i+4))>>2)];
  5667. view[i+2] = HEAP32[(((value)+(4*i+8))>>2)];
  5668. }
  5669. } else
  5670. {
  5671. var view = HEAP32.subarray((((value)>>2)), ((value+count*12)>>2));
  5672. }
  5673. GLctx.uniform3iv(webglGetUniformLocation(location), view);
  5674. };
  5675. var _emscripten_glUniform3iv = _glUniform3iv;
  5676. /** @suppress {duplicate } */
  5677. var _glUniform4f = (location, v0, v1, v2, v3) => {
  5678. GLctx.uniform4f(webglGetUniformLocation(location), v0, v1, v2, v3);
  5679. };
  5680. var _emscripten_glUniform4f = _glUniform4f;
  5681. /** @suppress {duplicate } */
  5682. var _glUniform4fv = (location, count, value) => {
  5683. if (count <= 72) {
  5684. // avoid allocation when uploading few enough uniforms
  5685. var view = miniTempWebGLFloatBuffers[4*count];
  5686. // hoist the heap out of the loop for size and for pthreads+growth.
  5687. var heap = HEAPF32;
  5688. value = ((value)>>2);
  5689. count *= 4;
  5690. for (var i = 0; i < count; i += 4) {
  5691. var dst = value + i;
  5692. view[i] = heap[dst];
  5693. view[i + 1] = heap[dst + 1];
  5694. view[i + 2] = heap[dst + 2];
  5695. view[i + 3] = heap[dst + 3];
  5696. }
  5697. } else
  5698. {
  5699. var view = HEAPF32.subarray((((value)>>2)), ((value+count*16)>>2));
  5700. }
  5701. GLctx.uniform4fv(webglGetUniformLocation(location), view);
  5702. };
  5703. var _emscripten_glUniform4fv = _glUniform4fv;
  5704. /** @suppress {duplicate } */
  5705. var _glUniform4i = (location, v0, v1, v2, v3) => {
  5706. GLctx.uniform4i(webglGetUniformLocation(location), v0, v1, v2, v3);
  5707. };
  5708. var _emscripten_glUniform4i = _glUniform4i;
  5709. /** @suppress {duplicate } */
  5710. var _glUniform4iv = (location, count, value) => {
  5711. if (count <= 72) {
  5712. // avoid allocation when uploading few enough uniforms
  5713. count *= 4;
  5714. var view = miniTempWebGLIntBuffers[count];
  5715. for (var i = 0; i < count; i += 4) {
  5716. view[i] = HEAP32[(((value)+(4*i))>>2)];
  5717. view[i+1] = HEAP32[(((value)+(4*i+4))>>2)];
  5718. view[i+2] = HEAP32[(((value)+(4*i+8))>>2)];
  5719. view[i+3] = HEAP32[(((value)+(4*i+12))>>2)];
  5720. }
  5721. } else
  5722. {
  5723. var view = HEAP32.subarray((((value)>>2)), ((value+count*16)>>2));
  5724. }
  5725. GLctx.uniform4iv(webglGetUniformLocation(location), view);
  5726. };
  5727. var _emscripten_glUniform4iv = _glUniform4iv;
  5728. /** @suppress {duplicate } */
  5729. var _glUniformMatrix2fv = (location, count, transpose, value) => {
  5730. if (count <= 72) {
  5731. // avoid allocation when uploading few enough uniforms
  5732. count *= 4;
  5733. var view = miniTempWebGLFloatBuffers[count];
  5734. for (var i = 0; i < count; i += 4) {
  5735. view[i] = HEAPF32[(((value)+(4*i))>>2)];
  5736. view[i+1] = HEAPF32[(((value)+(4*i+4))>>2)];
  5737. view[i+2] = HEAPF32[(((value)+(4*i+8))>>2)];
  5738. view[i+3] = HEAPF32[(((value)+(4*i+12))>>2)];
  5739. }
  5740. } else
  5741. {
  5742. var view = HEAPF32.subarray((((value)>>2)), ((value+count*16)>>2));
  5743. }
  5744. GLctx.uniformMatrix2fv(webglGetUniformLocation(location), !!transpose, view);
  5745. };
  5746. var _emscripten_glUniformMatrix2fv = _glUniformMatrix2fv;
  5747. /** @suppress {duplicate } */
  5748. var _glUniformMatrix3fv = (location, count, transpose, value) => {
  5749. if (count <= 32) {
  5750. // avoid allocation when uploading few enough uniforms
  5751. count *= 9;
  5752. var view = miniTempWebGLFloatBuffers[count];
  5753. for (var i = 0; i < count; i += 9) {
  5754. view[i] = HEAPF32[(((value)+(4*i))>>2)];
  5755. view[i+1] = HEAPF32[(((value)+(4*i+4))>>2)];
  5756. view[i+2] = HEAPF32[(((value)+(4*i+8))>>2)];
  5757. view[i+3] = HEAPF32[(((value)+(4*i+12))>>2)];
  5758. view[i+4] = HEAPF32[(((value)+(4*i+16))>>2)];
  5759. view[i+5] = HEAPF32[(((value)+(4*i+20))>>2)];
  5760. view[i+6] = HEAPF32[(((value)+(4*i+24))>>2)];
  5761. view[i+7] = HEAPF32[(((value)+(4*i+28))>>2)];
  5762. view[i+8] = HEAPF32[(((value)+(4*i+32))>>2)];
  5763. }
  5764. } else
  5765. {
  5766. var view = HEAPF32.subarray((((value)>>2)), ((value+count*36)>>2));
  5767. }
  5768. GLctx.uniformMatrix3fv(webglGetUniformLocation(location), !!transpose, view);
  5769. };
  5770. var _emscripten_glUniformMatrix3fv = _glUniformMatrix3fv;
  5771. /** @suppress {duplicate } */
  5772. var _glUniformMatrix4fv = (location, count, transpose, value) => {
  5773. if (count <= 18) {
  5774. // avoid allocation when uploading few enough uniforms
  5775. var view = miniTempWebGLFloatBuffers[16*count];
  5776. // hoist the heap out of the loop for size and for pthreads+growth.
  5777. var heap = HEAPF32;
  5778. value = ((value)>>2);
  5779. count *= 16;
  5780. for (var i = 0; i < count; i += 16) {
  5781. var dst = value + i;
  5782. view[i] = heap[dst];
  5783. view[i + 1] = heap[dst + 1];
  5784. view[i + 2] = heap[dst + 2];
  5785. view[i + 3] = heap[dst + 3];
  5786. view[i + 4] = heap[dst + 4];
  5787. view[i + 5] = heap[dst + 5];
  5788. view[i + 6] = heap[dst + 6];
  5789. view[i + 7] = heap[dst + 7];
  5790. view[i + 8] = heap[dst + 8];
  5791. view[i + 9] = heap[dst + 9];
  5792. view[i + 10] = heap[dst + 10];
  5793. view[i + 11] = heap[dst + 11];
  5794. view[i + 12] = heap[dst + 12];
  5795. view[i + 13] = heap[dst + 13];
  5796. view[i + 14] = heap[dst + 14];
  5797. view[i + 15] = heap[dst + 15];
  5798. }
  5799. } else
  5800. {
  5801. var view = HEAPF32.subarray((((value)>>2)), ((value+count*64)>>2));
  5802. }
  5803. GLctx.uniformMatrix4fv(webglGetUniformLocation(location), !!transpose, view);
  5804. };
  5805. var _emscripten_glUniformMatrix4fv = _glUniformMatrix4fv;
  5806. /** @suppress {duplicate } */
  5807. var _glUseProgram = (program) => {
  5808. program = GL.programs[program];
  5809. GLctx.useProgram(program);
  5810. // Record the currently active program so that we can access the uniform
  5811. // mapping table of that program.
  5812. GLctx.currentProgram = program;
  5813. };
  5814. var _emscripten_glUseProgram = _glUseProgram;
  5815. /** @suppress {duplicate } */
  5816. var _glValidateProgram = (program) => {
  5817. GLctx.validateProgram(GL.programs[program]);
  5818. };
  5819. var _emscripten_glValidateProgram = _glValidateProgram;
  5820. /** @suppress {duplicate } */
  5821. var _glVertexAttrib1f = (x0, x1) => GLctx.vertexAttrib1f(x0, x1);
  5822. var _emscripten_glVertexAttrib1f = _glVertexAttrib1f;
  5823. /** @suppress {duplicate } */
  5824. var _glVertexAttrib1fv = (index, v) => {
  5825. GLctx.vertexAttrib1f(index, HEAPF32[v>>2]);
  5826. };
  5827. var _emscripten_glVertexAttrib1fv = _glVertexAttrib1fv;
  5828. /** @suppress {duplicate } */
  5829. var _glVertexAttrib2f = (x0, x1, x2) => GLctx.vertexAttrib2f(x0, x1, x2);
  5830. var _emscripten_glVertexAttrib2f = _glVertexAttrib2f;
  5831. /** @suppress {duplicate } */
  5832. var _glVertexAttrib2fv = (index, v) => {
  5833. GLctx.vertexAttrib2f(index, HEAPF32[v>>2], HEAPF32[v+4>>2]);
  5834. };
  5835. var _emscripten_glVertexAttrib2fv = _glVertexAttrib2fv;
  5836. /** @suppress {duplicate } */
  5837. var _glVertexAttrib3f = (x0, x1, x2, x3) => GLctx.vertexAttrib3f(x0, x1, x2, x3);
  5838. var _emscripten_glVertexAttrib3f = _glVertexAttrib3f;
  5839. /** @suppress {duplicate } */
  5840. var _glVertexAttrib3fv = (index, v) => {
  5841. GLctx.vertexAttrib3f(index, HEAPF32[v>>2], HEAPF32[v+4>>2], HEAPF32[v+8>>2]);
  5842. };
  5843. var _emscripten_glVertexAttrib3fv = _glVertexAttrib3fv;
  5844. /** @suppress {duplicate } */
  5845. var _glVertexAttrib4f = (x0, x1, x2, x3, x4) => GLctx.vertexAttrib4f(x0, x1, x2, x3, x4);
  5846. var _emscripten_glVertexAttrib4f = _glVertexAttrib4f;
  5847. /** @suppress {duplicate } */
  5848. var _glVertexAttrib4fv = (index, v) => {
  5849. GLctx.vertexAttrib4f(index, HEAPF32[v>>2], HEAPF32[v+4>>2], HEAPF32[v+8>>2], HEAPF32[v+12>>2]);
  5850. };
  5851. var _emscripten_glVertexAttrib4fv = _glVertexAttrib4fv;
  5852. /** @suppress {duplicate } */
  5853. var _glVertexAttribDivisor = (index, divisor) => {
  5854. GLctx.vertexAttribDivisor(index, divisor);
  5855. };
  5856. /** @suppress {duplicate } */
  5857. var _glVertexAttribDivisorANGLE = _glVertexAttribDivisor;
  5858. var _emscripten_glVertexAttribDivisorANGLE = _glVertexAttribDivisorANGLE;
  5859. /** @suppress {duplicate } */
  5860. var _glVertexAttribPointer = (index, size, type, normalized, stride, ptr) => {
  5861. GLctx.vertexAttribPointer(index, size, type, !!normalized, stride, ptr);
  5862. };
  5863. var _emscripten_glVertexAttribPointer = _glVertexAttribPointer;
  5864. /** @suppress {duplicate } */
  5865. var _glViewport = (x0, x1, x2, x3) => GLctx.viewport(x0, x1, x2, x3);
  5866. var _emscripten_glViewport = _glViewport;
  5867. var getHeapMax = () =>
  5868. HEAPU8.length;
  5869. var abortOnCannotGrowMemory = (requestedSize) => {
  5870. abort(`Cannot enlarge memory arrays to size ${requestedSize} bytes (OOM). Either (1) compile with -sINITIAL_MEMORY=X with X higher than the current value ${HEAP8.length}, (2) compile with -sALLOW_MEMORY_GROWTH which allows increasing the size at runtime, or (3) if you want malloc to return NULL (0) instead of this abort, compile with -sABORTING_MALLOC=0`);
  5871. };
  5872. var _emscripten_resize_heap = (requestedSize) => {
  5873. var oldSize = HEAPU8.length;
  5874. // With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned.
  5875. requestedSize >>>= 0;
  5876. abortOnCannotGrowMemory(requestedSize);
  5877. };
  5878. /** @suppress {checkTypes} */
  5879. var _emscripten_sample_gamepad_data = () => {
  5880. try {
  5881. if (navigator.getGamepads) return (JSEvents.lastGamepadState = navigator.getGamepads())
  5882. ? 0 : -1;
  5883. } catch(e) {
  5884. err(`navigator.getGamepads() exists, but failed to execute with exception ${e}. Disabling Gamepad access.`);
  5885. navigator.getGamepads = null; // Disable getGamepads() so that it won't be attempted to be used again.
  5886. }
  5887. return -1;
  5888. };
  5889. var findCanvasEventTarget = findEventTarget;
  5890. var _emscripten_set_canvas_element_size = (target, width, height) => {
  5891. var canvas = findCanvasEventTarget(target);
  5892. if (!canvas) return -4;
  5893. canvas.width = width;
  5894. canvas.height = height;
  5895. return 0;
  5896. };
  5897. var fillMouseEventData = (eventStruct, e, target) => {
  5898. assert(eventStruct % 4 == 0);
  5899. HEAPF64[((eventStruct)>>3)] = e.timeStamp;
  5900. var idx = ((eventStruct)>>2);
  5901. HEAP32[idx + 2] = e.screenX;
  5902. HEAP32[idx + 3] = e.screenY;
  5903. HEAP32[idx + 4] = e.clientX;
  5904. HEAP32[idx + 5] = e.clientY;
  5905. HEAP8[eventStruct + 24] = e.ctrlKey;
  5906. HEAP8[eventStruct + 25] = e.shiftKey;
  5907. HEAP8[eventStruct + 26] = e.altKey;
  5908. HEAP8[eventStruct + 27] = e.metaKey;
  5909. HEAP16[idx*2 + 14] = e.button;
  5910. HEAP16[idx*2 + 15] = e.buttons;
  5911. HEAP32[idx + 8] = e["movementX"]
  5912. ;
  5913. HEAP32[idx + 9] = e["movementY"]
  5914. ;
  5915. // Note: rect contains doubles (truncated to placate SAFE_HEAP, which is the same behaviour when writing to HEAP32 anyway)
  5916. var rect = getBoundingClientRect(target);
  5917. HEAP32[idx + 10] = e.clientX - (rect.left | 0);
  5918. HEAP32[idx + 11] = e.clientY - (rect.top | 0);
  5919. };
  5920. var wasmTableMirror = [];
  5921. /** @type {WebAssembly.Table} */
  5922. var wasmTable;
  5923. var getWasmTableEntry = (funcPtr) => {
  5924. var func = wasmTableMirror[funcPtr];
  5925. if (!func) {
  5926. if (funcPtr >= wasmTableMirror.length) wasmTableMirror.length = funcPtr + 1;
  5927. /** @suppress {checkTypes} */
  5928. wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr);
  5929. }
  5930. /** @suppress {checkTypes} */
  5931. assert(wasmTable.get(funcPtr) == func, 'JavaScript-side Wasm function table mirror is out of date!');
  5932. return func;
  5933. };
  5934. var registerMouseEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  5935. JSEvents.mouseEvent ||= _malloc(64);
  5936. target = findEventTarget(target);
  5937. var mouseEventHandlerFunc = (e = event) => {
  5938. // TODO: Make this access thread safe, or this could update live while app is reading it.
  5939. fillMouseEventData(JSEvents.mouseEvent, e, target);
  5940. if (getWasmTableEntry(callbackfunc)(eventTypeId, JSEvents.mouseEvent, userData)) e.preventDefault();
  5941. };
  5942. var eventHandler = {
  5943. target,
  5944. allowsDeferredCalls: eventTypeString != 'mousemove' && eventTypeString != 'mouseenter' && eventTypeString != 'mouseleave', // Mouse move events do not allow fullscreen/pointer lock requests to be handled in them!
  5945. eventTypeString,
  5946. callbackfunc,
  5947. handlerFunc: mouseEventHandlerFunc,
  5948. useCapture
  5949. };
  5950. return JSEvents.registerOrRemoveHandler(eventHandler);
  5951. };
  5952. var _emscripten_set_click_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  5953. registerMouseEventCallback(target, userData, useCapture, callbackfunc, 4, "click", targetThread);
  5954. var fillFullscreenChangeEventData = (eventStruct) => {
  5955. var fullscreenElement = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement;
  5956. var isFullscreen = !!fullscreenElement;
  5957. // Assigning a boolean to HEAP32 with expected type coercion.
  5958. /** @suppress{checkTypes} */
  5959. HEAP8[eventStruct] = isFullscreen;
  5960. HEAP8[(eventStruct)+(1)] = JSEvents.fullscreenEnabled();
  5961. // If transitioning to fullscreen, report info about the element that is now fullscreen.
  5962. // If transitioning to windowed mode, report info about the element that just was fullscreen.
  5963. var reportedElement = isFullscreen ? fullscreenElement : JSEvents.previousFullscreenElement;
  5964. var nodeName = JSEvents.getNodeNameForTarget(reportedElement);
  5965. var id = reportedElement?.id || '';
  5966. stringToUTF8(nodeName, eventStruct + 2, 128);
  5967. stringToUTF8(id, eventStruct + 130, 128);
  5968. HEAP32[(((eventStruct)+(260))>>2)] = reportedElement ? reportedElement.clientWidth : 0;
  5969. HEAP32[(((eventStruct)+(264))>>2)] = reportedElement ? reportedElement.clientHeight : 0;
  5970. HEAP32[(((eventStruct)+(268))>>2)] = screen.width;
  5971. HEAP32[(((eventStruct)+(272))>>2)] = screen.height;
  5972. if (isFullscreen) {
  5973. JSEvents.previousFullscreenElement = fullscreenElement;
  5974. }
  5975. };
  5976. var registerFullscreenChangeEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  5977. JSEvents.fullscreenChangeEvent ||= _malloc(276);
  5978. var fullscreenChangeEventhandlerFunc = (e = event) => {
  5979. var fullscreenChangeEvent = JSEvents.fullscreenChangeEvent;
  5980. fillFullscreenChangeEventData(fullscreenChangeEvent);
  5981. if (getWasmTableEntry(callbackfunc)(eventTypeId, fullscreenChangeEvent, userData)) e.preventDefault();
  5982. };
  5983. var eventHandler = {
  5984. target,
  5985. eventTypeString,
  5986. callbackfunc,
  5987. handlerFunc: fullscreenChangeEventhandlerFunc,
  5988. useCapture
  5989. };
  5990. return JSEvents.registerOrRemoveHandler(eventHandler);
  5991. };
  5992. var _emscripten_set_fullscreenchange_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) => {
  5993. if (!JSEvents.fullscreenEnabled()) return -1;
  5994. target = findEventTarget(target);
  5995. if (!target) return -4;
  5996. // Unprefixed Fullscreen API shipped in Chromium 71 (https://bugs.chromium.org/p/chromium/issues/detail?id=383813)
  5997. // 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.
  5998. registerFullscreenChangeEventCallback(target, userData, useCapture, callbackfunc, 19, "webkitfullscreenchange", targetThread);
  5999. return registerFullscreenChangeEventCallback(target, userData, useCapture, callbackfunc, 19, "fullscreenchange", targetThread);
  6000. };
  6001. var registerGamepadEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  6002. JSEvents.gamepadEvent ||= _malloc(1240);
  6003. var gamepadEventHandlerFunc = (e = event) => {
  6004. var gamepadEvent = JSEvents.gamepadEvent;
  6005. fillGamepadEventData(gamepadEvent, e["gamepad"]);
  6006. if (getWasmTableEntry(callbackfunc)(eventTypeId, gamepadEvent, userData)) e.preventDefault();
  6007. };
  6008. var eventHandler = {
  6009. target: findEventTarget(target),
  6010. allowsDeferredCalls: true,
  6011. eventTypeString,
  6012. callbackfunc,
  6013. handlerFunc: gamepadEventHandlerFunc,
  6014. useCapture
  6015. };
  6016. return JSEvents.registerOrRemoveHandler(eventHandler);
  6017. };
  6018. var _emscripten_set_gamepadconnected_callback_on_thread = (userData, useCapture, callbackfunc, targetThread) => {
  6019. if (_emscripten_sample_gamepad_data()) return -1;
  6020. return registerGamepadEventCallback(2, userData, useCapture, callbackfunc, 26, "gamepadconnected", targetThread);
  6021. };
  6022. var _emscripten_set_gamepaddisconnected_callback_on_thread = (userData, useCapture, callbackfunc, targetThread) => {
  6023. if (_emscripten_sample_gamepad_data()) return -1;
  6024. return registerGamepadEventCallback(2, userData, useCapture, callbackfunc, 27, "gamepaddisconnected", targetThread);
  6025. };
  6026. var handleException = (e) => {
  6027. // Certain exception types we do not treat as errors since they are used for
  6028. // internal control flow.
  6029. // 1. ExitStatus, which is thrown by exit()
  6030. // 2. "unwind", which is thrown by emscripten_unwind_to_js_event_loop() and others
  6031. // that wish to return to JS event loop.
  6032. if (e instanceof ExitStatus || e == 'unwind') {
  6033. return EXITSTATUS;
  6034. }
  6035. checkStackCookie();
  6036. if (e instanceof WebAssembly.RuntimeError) {
  6037. if (_emscripten_stack_get_current() <= 0) {
  6038. err('Stack overflow detected. You can try increasing -sSTACK_SIZE (currently set to 65536)');
  6039. }
  6040. }
  6041. quit_(1, e);
  6042. };
  6043. var runtimeKeepaliveCounter = 0;
  6044. var keepRuntimeAlive = () => noExitRuntime || runtimeKeepaliveCounter > 0;
  6045. var _proc_exit = (code) => {
  6046. EXITSTATUS = code;
  6047. if (!keepRuntimeAlive()) {
  6048. Module['onExit']?.(code);
  6049. ABORT = true;
  6050. }
  6051. quit_(code, new ExitStatus(code));
  6052. };
  6053. /** @suppress {duplicate } */
  6054. /** @param {boolean|number=} implicit */
  6055. var exitJS = (status, implicit) => {
  6056. EXITSTATUS = status;
  6057. checkUnflushedContent();
  6058. // if exit() was called explicitly, warn the user if the runtime isn't actually being shut down
  6059. if (keepRuntimeAlive() && !implicit) {
  6060. 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)`;
  6061. err(msg);
  6062. }
  6063. _proc_exit(status);
  6064. };
  6065. var _exit = exitJS;
  6066. var maybeExit = () => {
  6067. if (!keepRuntimeAlive()) {
  6068. try {
  6069. _exit(EXITSTATUS);
  6070. } catch (e) {
  6071. handleException(e);
  6072. }
  6073. }
  6074. };
  6075. var callUserCallback = (func) => {
  6076. if (ABORT) {
  6077. err('user callback triggered after runtime exited or application aborted. Ignoring.');
  6078. return;
  6079. }
  6080. try {
  6081. func();
  6082. maybeExit();
  6083. } catch (e) {
  6084. handleException(e);
  6085. }
  6086. };
  6087. var _emscripten_set_main_loop_timing = (mode, value) => {
  6088. MainLoop.timingMode = mode;
  6089. MainLoop.timingValue = value;
  6090. if (!MainLoop.func) {
  6091. 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.');
  6092. return 1; // Return non-zero on failure, can't set timing mode when there is no main loop.
  6093. }
  6094. if (!MainLoop.running) {
  6095. MainLoop.running = true;
  6096. }
  6097. if (mode == 0) {
  6098. MainLoop.scheduler = function MainLoop_scheduler_setTimeout() {
  6099. var timeUntilNextTick = Math.max(0, MainLoop.tickStartTime + value - _emscripten_get_now())|0;
  6100. setTimeout(MainLoop.runner, timeUntilNextTick); // doing this each time means that on exception, we stop
  6101. };
  6102. MainLoop.method = 'timeout';
  6103. } else if (mode == 1) {
  6104. MainLoop.scheduler = function MainLoop_scheduler_rAF() {
  6105. MainLoop.requestAnimationFrame(MainLoop.runner);
  6106. };
  6107. MainLoop.method = 'rAF';
  6108. } else if (mode == 2) {
  6109. if (typeof MainLoop.setImmediate == 'undefined') {
  6110. if (typeof setImmediate == 'undefined') {
  6111. // Emulate setImmediate. (note: not a complete polyfill, we don't emulate clearImmediate() to keep code size to minimum, since not needed)
  6112. var setImmediates = [];
  6113. var emscriptenMainLoopMessageId = 'setimmediate';
  6114. /** @param {Event} event */
  6115. var MainLoop_setImmediate_messageHandler = (event) => {
  6116. // 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,
  6117. // so check for both cases.
  6118. if (event.data === emscriptenMainLoopMessageId || event.data.target === emscriptenMainLoopMessageId) {
  6119. event.stopPropagation();
  6120. setImmediates.shift()();
  6121. }
  6122. };
  6123. addEventListener("message", MainLoop_setImmediate_messageHandler, true);
  6124. MainLoop.setImmediate = /** @type{function(function(): ?, ...?): number} */((func) => {
  6125. setImmediates.push(func);
  6126. if (ENVIRONMENT_IS_WORKER) {
  6127. Module['setImmediates'] ??= [];
  6128. Module['setImmediates'].push(func);
  6129. postMessage({target: emscriptenMainLoopMessageId}); // In --proxy-to-worker, route the message via proxyClient.js
  6130. } else postMessage(emscriptenMainLoopMessageId, "*"); // On the main thread, can just send the message to itself.
  6131. });
  6132. } else {
  6133. MainLoop.setImmediate = setImmediate;
  6134. }
  6135. }
  6136. MainLoop.scheduler = function MainLoop_scheduler_setImmediate() {
  6137. MainLoop.setImmediate(MainLoop.runner);
  6138. };
  6139. MainLoop.method = 'immediate';
  6140. }
  6141. return 0;
  6142. };
  6143. var MainLoop = {
  6144. running:false,
  6145. scheduler:null,
  6146. method:"",
  6147. currentlyRunningMainloop:0,
  6148. func:null,
  6149. arg:0,
  6150. timingMode:0,
  6151. timingValue:0,
  6152. currentFrameNumber:0,
  6153. queue:[],
  6154. preMainLoop:[],
  6155. postMainLoop:[],
  6156. pause() {
  6157. MainLoop.scheduler = null;
  6158. // Incrementing this signals the previous main loop that it's now become old, and it must return.
  6159. MainLoop.currentlyRunningMainloop++;
  6160. },
  6161. resume() {
  6162. MainLoop.currentlyRunningMainloop++;
  6163. var timingMode = MainLoop.timingMode;
  6164. var timingValue = MainLoop.timingValue;
  6165. var func = MainLoop.func;
  6166. MainLoop.func = null;
  6167. // do not set timing and call scheduler, we will do it on the next lines
  6168. setMainLoop(func, 0, false, MainLoop.arg, true);
  6169. _emscripten_set_main_loop_timing(timingMode, timingValue);
  6170. MainLoop.scheduler();
  6171. },
  6172. updateStatus() {
  6173. if (Module['setStatus']) {
  6174. var message = Module['statusMessage'] || 'Please wait...';
  6175. var remaining = MainLoop.remainingBlockers ?? 0;
  6176. var expected = MainLoop.expectedBlockers ?? 0;
  6177. if (remaining) {
  6178. if (remaining < expected) {
  6179. Module['setStatus'](`{message} ({expected - remaining}/{expected})`);
  6180. } else {
  6181. Module['setStatus'](message);
  6182. }
  6183. } else {
  6184. Module['setStatus']('');
  6185. }
  6186. }
  6187. },
  6188. init() {
  6189. Module['preMainLoop'] && MainLoop.preMainLoop.push(Module['preMainLoop']);
  6190. Module['postMainLoop'] && MainLoop.postMainLoop.push(Module['postMainLoop']);
  6191. },
  6192. runIter(func) {
  6193. if (ABORT) return;
  6194. for (var pre of MainLoop.preMainLoop) {
  6195. if (pre() === false) {
  6196. return; // |return false| skips a frame
  6197. }
  6198. }
  6199. callUserCallback(func);
  6200. for (var post of MainLoop.postMainLoop) {
  6201. post();
  6202. }
  6203. checkStackCookie();
  6204. },
  6205. nextRAF:0,
  6206. fakeRequestAnimationFrame(func) {
  6207. // try to keep 60fps between calls to here
  6208. var now = Date.now();
  6209. if (MainLoop.nextRAF === 0) {
  6210. MainLoop.nextRAF = now + 1000/60;
  6211. } else {
  6212. while (now + 2 >= MainLoop.nextRAF) { // fudge a little, to avoid timer jitter causing us to do lots of delay:0
  6213. MainLoop.nextRAF += 1000/60;
  6214. }
  6215. }
  6216. var delay = Math.max(MainLoop.nextRAF - now, 0);
  6217. setTimeout(func, delay);
  6218. },
  6219. requestAnimationFrame(func) {
  6220. if (typeof requestAnimationFrame == 'function') {
  6221. requestAnimationFrame(func);
  6222. return;
  6223. }
  6224. var RAF = MainLoop.fakeRequestAnimationFrame;
  6225. RAF(func);
  6226. },
  6227. };
  6228. /**
  6229. * @param {number=} arg
  6230. * @param {boolean=} noSetTiming
  6231. */
  6232. var setMainLoop = (iterFunc, fps, simulateInfiniteLoop, arg, noSetTiming) => {
  6233. 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.');
  6234. MainLoop.func = iterFunc;
  6235. MainLoop.arg = arg;
  6236. var thisMainLoopId = MainLoop.currentlyRunningMainloop;
  6237. function checkIsRunning() {
  6238. if (thisMainLoopId < MainLoop.currentlyRunningMainloop) {
  6239. maybeExit();
  6240. return false;
  6241. }
  6242. return true;
  6243. }
  6244. // We create the loop runner here but it is not actually running until
  6245. // _emscripten_set_main_loop_timing is called (which might happen a
  6246. // later time). This member signifies that the current runner has not
  6247. // yet been started so that we can call runtimeKeepalivePush when it
  6248. // gets it timing set for the first time.
  6249. MainLoop.running = false;
  6250. MainLoop.runner = function MainLoop_runner() {
  6251. if (ABORT) return;
  6252. if (MainLoop.queue.length > 0) {
  6253. var start = Date.now();
  6254. var blocker = MainLoop.queue.shift();
  6255. blocker.func(blocker.arg);
  6256. if (MainLoop.remainingBlockers) {
  6257. var remaining = MainLoop.remainingBlockers;
  6258. var next = remaining%1 == 0 ? remaining-1 : Math.floor(remaining);
  6259. if (blocker.counted) {
  6260. MainLoop.remainingBlockers = next;
  6261. } else {
  6262. // not counted, but move the progress along a tiny bit
  6263. next = next + 0.5; // do not steal all the next one's progress
  6264. MainLoop.remainingBlockers = (8*remaining + next)/9;
  6265. }
  6266. }
  6267. MainLoop.updateStatus();
  6268. // catches pause/resume main loop from blocker execution
  6269. if (!checkIsRunning()) return;
  6270. setTimeout(MainLoop.runner, 0);
  6271. return;
  6272. }
  6273. // catch pauses from non-main loop sources
  6274. if (!checkIsRunning()) return;
  6275. // Implement very basic swap interval control
  6276. MainLoop.currentFrameNumber = MainLoop.currentFrameNumber + 1 | 0;
  6277. if (MainLoop.timingMode == 1 && MainLoop.timingValue > 1 && MainLoop.currentFrameNumber % MainLoop.timingValue != 0) {
  6278. // Not the scheduled time to render this frame - skip.
  6279. MainLoop.scheduler();
  6280. return;
  6281. } else if (MainLoop.timingMode == 0) {
  6282. MainLoop.tickStartTime = _emscripten_get_now();
  6283. }
  6284. if (MainLoop.method === 'timeout' && Module['ctx']) {
  6285. 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!');
  6286. MainLoop.method = ''; // just warn once per call to set main loop
  6287. }
  6288. MainLoop.runIter(iterFunc);
  6289. // catch pauses from the main loop itself
  6290. if (!checkIsRunning()) return;
  6291. MainLoop.scheduler();
  6292. }
  6293. if (!noSetTiming) {
  6294. if (fps > 0) {
  6295. _emscripten_set_main_loop_timing(0, 1000.0 / fps);
  6296. } else {
  6297. // Do rAF by rendering each frame (no decimating)
  6298. _emscripten_set_main_loop_timing(1, 1);
  6299. }
  6300. MainLoop.scheduler();
  6301. }
  6302. if (simulateInfiniteLoop) {
  6303. throw 'unwind';
  6304. }
  6305. };
  6306. var _emscripten_set_main_loop = (func, fps, simulateInfiniteLoop) => {
  6307. var iterFunc = getWasmTableEntry(func);
  6308. setMainLoop(iterFunc, fps, simulateInfiniteLoop);
  6309. };
  6310. var _emscripten_set_mousemove_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  6311. registerMouseEventCallback(target, userData, useCapture, callbackfunc, 8, "mousemove", targetThread);
  6312. var fillPointerlockChangeEventData = (eventStruct) => {
  6313. var pointerLockElement = document.pointerLockElement || document.mozPointerLockElement || document.webkitPointerLockElement || document.msPointerLockElement;
  6314. var isPointerlocked = !!pointerLockElement;
  6315. // Assigning a boolean to HEAP32 with expected type coercion.
  6316. /** @suppress{checkTypes} */
  6317. HEAP8[eventStruct] = isPointerlocked;
  6318. var nodeName = JSEvents.getNodeNameForTarget(pointerLockElement);
  6319. var id = pointerLockElement?.id || '';
  6320. stringToUTF8(nodeName, eventStruct + 1, 128);
  6321. stringToUTF8(id, eventStruct + 129, 128);
  6322. };
  6323. var registerPointerlockChangeEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  6324. JSEvents.pointerlockChangeEvent ||= _malloc(257);
  6325. var pointerlockChangeEventHandlerFunc = (e = event) => {
  6326. var pointerlockChangeEvent = JSEvents.pointerlockChangeEvent;
  6327. fillPointerlockChangeEventData(pointerlockChangeEvent);
  6328. if (getWasmTableEntry(callbackfunc)(eventTypeId, pointerlockChangeEvent, userData)) e.preventDefault();
  6329. };
  6330. var eventHandler = {
  6331. target,
  6332. eventTypeString,
  6333. callbackfunc,
  6334. handlerFunc: pointerlockChangeEventHandlerFunc,
  6335. useCapture
  6336. };
  6337. return JSEvents.registerOrRemoveHandler(eventHandler);
  6338. };
  6339. /** @suppress {missingProperties} */
  6340. var _emscripten_set_pointerlockchange_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) => {
  6341. // TODO: Currently not supported in pthreads or in --proxy-to-worker mode. (In pthreads mode, document object is not defined)
  6342. if (!document || !document.body || (!document.body.requestPointerLock && !document.body.mozRequestPointerLock && !document.body.webkitRequestPointerLock && !document.body.msRequestPointerLock)) {
  6343. return -1;
  6344. }
  6345. target = findEventTarget(target);
  6346. if (!target) return -4;
  6347. registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "mozpointerlockchange", targetThread);
  6348. registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "webkitpointerlockchange", targetThread);
  6349. registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "mspointerlockchange", targetThread);
  6350. return registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "pointerlockchange", targetThread);
  6351. };
  6352. var registerUiEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  6353. JSEvents.uiEvent ||= _malloc(36);
  6354. target = findEventTarget(target);
  6355. var uiEventHandlerFunc = (e = event) => {
  6356. if (e.target != target) {
  6357. // Never take ui events such as scroll via a 'bubbled' route, but always from the direct element that
  6358. // was targeted. Otherwise e.g. if app logs a message in response to a page scroll, the Emscripten log
  6359. // message box could cause to scroll, generating a new (bubbled) scroll message, causing a new log print,
  6360. // causing a new scroll, etc..
  6361. return;
  6362. }
  6363. var b = document.body; // Take document.body to a variable, Closure compiler does not outline access to it on its own.
  6364. if (!b) {
  6365. // During a page unload 'body' can be null, with "Cannot read property 'clientWidth' of null" being thrown
  6366. return;
  6367. }
  6368. var uiEvent = JSEvents.uiEvent;
  6369. HEAP32[((uiEvent)>>2)] = 0; // always zero for resize and scroll
  6370. HEAP32[(((uiEvent)+(4))>>2)] = b.clientWidth;
  6371. HEAP32[(((uiEvent)+(8))>>2)] = b.clientHeight;
  6372. HEAP32[(((uiEvent)+(12))>>2)] = innerWidth;
  6373. HEAP32[(((uiEvent)+(16))>>2)] = innerHeight;
  6374. HEAP32[(((uiEvent)+(20))>>2)] = outerWidth;
  6375. HEAP32[(((uiEvent)+(24))>>2)] = outerHeight;
  6376. HEAP32[(((uiEvent)+(28))>>2)] = pageXOffset | 0; // scroll offsets are float
  6377. HEAP32[(((uiEvent)+(32))>>2)] = pageYOffset | 0;
  6378. if (getWasmTableEntry(callbackfunc)(eventTypeId, uiEvent, userData)) e.preventDefault();
  6379. };
  6380. var eventHandler = {
  6381. target,
  6382. eventTypeString,
  6383. callbackfunc,
  6384. handlerFunc: uiEventHandlerFunc,
  6385. useCapture
  6386. };
  6387. return JSEvents.registerOrRemoveHandler(eventHandler);
  6388. };
  6389. var _emscripten_set_resize_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  6390. registerUiEventCallback(target, userData, useCapture, callbackfunc, 10, "resize", targetThread);
  6391. var registerTouchEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => {
  6392. JSEvents.touchEvent ||= _malloc(1552);
  6393. target = findEventTarget(target);
  6394. var touchEventHandlerFunc = (e) => {
  6395. assert(e);
  6396. var t, touches = {}, et = e.touches;
  6397. // To ease marshalling different kinds of touches that browser reports (all touches are listed in e.touches,
  6398. // only changed touches in e.changedTouches, and touches on target at a.targetTouches), mark a boolean in
  6399. // each Touch object so that we can later loop only once over all touches we see to marshall over to Wasm.
  6400. for (let t of et) {
  6401. // Browser might recycle the generated Touch objects between each frame (Firefox on Android), so reset any
  6402. // changed/target states we may have set from previous frame.
  6403. t.isChanged = t.onTarget = 0;
  6404. touches[t.identifier] = t;
  6405. }
  6406. // Mark which touches are part of the changedTouches list.
  6407. for (let t of e.changedTouches) {
  6408. t.isChanged = 1;
  6409. touches[t.identifier] = t;
  6410. }
  6411. // Mark which touches are part of the targetTouches list.
  6412. for (let t of e.targetTouches) {
  6413. touches[t.identifier].onTarget = 1;
  6414. }
  6415. var touchEvent = JSEvents.touchEvent;
  6416. HEAPF64[((touchEvent)>>3)] = e.timeStamp;
  6417. HEAP8[touchEvent + 12] = e.ctrlKey;
  6418. HEAP8[touchEvent + 13] = e.shiftKey;
  6419. HEAP8[touchEvent + 14] = e.altKey;
  6420. HEAP8[touchEvent + 15] = e.metaKey;
  6421. var idx = touchEvent + 16;
  6422. var targetRect = getBoundingClientRect(target);
  6423. var numTouches = 0;
  6424. for (let t of Object.values(touches)) {
  6425. var idx32 = ((idx)>>2); // Pre-shift the ptr to index to HEAP32 to save code size
  6426. HEAP32[idx32 + 0] = t.identifier;
  6427. HEAP32[idx32 + 1] = t.screenX;
  6428. HEAP32[idx32 + 2] = t.screenY;
  6429. HEAP32[idx32 + 3] = t.clientX;
  6430. HEAP32[idx32 + 4] = t.clientY;
  6431. HEAP32[idx32 + 5] = t.pageX;
  6432. HEAP32[idx32 + 6] = t.pageY;
  6433. HEAP8[idx + 28] = t.isChanged;
  6434. HEAP8[idx + 29] = t.onTarget;
  6435. HEAP32[idx32 + 8] = t.clientX - (targetRect.left | 0);
  6436. HEAP32[idx32 + 9] = t.clientY - (targetRect.top | 0);
  6437. idx += 48;
  6438. if (++numTouches > 31) {
  6439. break;
  6440. }
  6441. }
  6442. HEAP32[(((touchEvent)+(8))>>2)] = numTouches;
  6443. if (getWasmTableEntry(callbackfunc)(eventTypeId, touchEvent, userData)) e.preventDefault();
  6444. };
  6445. var eventHandler = {
  6446. target,
  6447. allowsDeferredCalls: eventTypeString == 'touchstart' || eventTypeString == 'touchend',
  6448. eventTypeString,
  6449. callbackfunc,
  6450. handlerFunc: touchEventHandlerFunc,
  6451. useCapture
  6452. };
  6453. return JSEvents.registerOrRemoveHandler(eventHandler);
  6454. };
  6455. var _emscripten_set_touchcancel_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  6456. registerTouchEventCallback(target, userData, useCapture, callbackfunc, 25, "touchcancel", targetThread);
  6457. var _emscripten_set_touchend_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  6458. registerTouchEventCallback(target, userData, useCapture, callbackfunc, 23, "touchend", targetThread);
  6459. var _emscripten_set_touchmove_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  6460. registerTouchEventCallback(target, userData, useCapture, callbackfunc, 24, "touchmove", targetThread);
  6461. var _emscripten_set_touchstart_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) =>
  6462. registerTouchEventCallback(target, userData, useCapture, callbackfunc, 22, "touchstart", targetThread);
  6463. /** @param {number=} timeout */
  6464. var safeSetTimeout = (func, timeout) => {
  6465. return setTimeout(() => {
  6466. callUserCallback(func);
  6467. }, timeout);
  6468. };
  6469. var Browser = {
  6470. useWebGL:false,
  6471. isFullscreen:false,
  6472. pointerLock:false,
  6473. moduleContextCreatedCallbacks:[],
  6474. workers:[],
  6475. preloadedImages:{
  6476. },
  6477. preloadedAudios:{
  6478. },
  6479. getCanvas:() => Module['canvas'],
  6480. init() {
  6481. if (Browser.initted) return;
  6482. Browser.initted = true;
  6483. // Support for plugins that can process preloaded files. You can add more of these to
  6484. // your app by creating and appending to preloadPlugins.
  6485. //
  6486. // Each plugin is asked if it can handle a file based on the file's name. If it can,
  6487. // it is given the file's raw data. When it is done, it calls a callback with the file's
  6488. // (possibly modified) data. For example, a plugin might decompress a file, or it
  6489. // might create some side data structure for use later (like an Image element, etc.).
  6490. var imagePlugin = {};
  6491. imagePlugin['canHandle'] = function imagePlugin_canHandle(name) {
  6492. return !Module['noImageDecoding'] && /\.(jpg|jpeg|png|bmp|webp)$/i.test(name);
  6493. };
  6494. imagePlugin['handle'] = function imagePlugin_handle(byteArray, name, onload, onerror) {
  6495. var b = new Blob([byteArray], { type: Browser.getMimetype(name) });
  6496. if (b.size !== byteArray.length) { // Safari bug #118630
  6497. // Safari's Blob can only take an ArrayBuffer
  6498. b = new Blob([(new Uint8Array(byteArray)).buffer], { type: Browser.getMimetype(name) });
  6499. }
  6500. var url = URL.createObjectURL(b);
  6501. assert(typeof url == 'string', 'createObjectURL must return a url as a string');
  6502. var img = new Image();
  6503. img.onload = () => {
  6504. assert(img.complete, `Image ${name} could not be decoded`);
  6505. var canvas = /** @type {!HTMLCanvasElement} */ (document.createElement('canvas'));
  6506. canvas.width = img.width;
  6507. canvas.height = img.height;
  6508. var ctx = canvas.getContext('2d');
  6509. ctx.drawImage(img, 0, 0);
  6510. Browser.preloadedImages[name] = canvas;
  6511. URL.revokeObjectURL(url);
  6512. onload?.(byteArray);
  6513. };
  6514. img.onerror = (event) => {
  6515. err(`Image ${url} could not be decoded`);
  6516. onerror?.();
  6517. };
  6518. img.src = url;
  6519. };
  6520. preloadPlugins.push(imagePlugin);
  6521. var audioPlugin = {};
  6522. audioPlugin['canHandle'] = function audioPlugin_canHandle(name) {
  6523. return !Module['noAudioDecoding'] && name.slice(-4) in { '.ogg': 1, '.wav': 1, '.mp3': 1 };
  6524. };
  6525. audioPlugin['handle'] = function audioPlugin_handle(byteArray, name, onload, onerror) {
  6526. var done = false;
  6527. function finish(audio) {
  6528. if (done) return;
  6529. done = true;
  6530. Browser.preloadedAudios[name] = audio;
  6531. onload?.(byteArray);
  6532. }
  6533. function fail() {
  6534. if (done) return;
  6535. done = true;
  6536. Browser.preloadedAudios[name] = new Audio(); // empty shim
  6537. onerror?.();
  6538. }
  6539. var b = new Blob([byteArray], { type: Browser.getMimetype(name) });
  6540. var url = URL.createObjectURL(b); // XXX we never revoke this!
  6541. assert(typeof url == 'string', 'createObjectURL must return a url as a string');
  6542. var audio = new Audio();
  6543. audio.addEventListener('canplaythrough', () => finish(audio), false); // use addEventListener due to chromium bug 124926
  6544. audio.onerror = function audio_onerror(event) {
  6545. if (done) return;
  6546. err(`warning: browser could not fully decode audio ${name}, trying slower base64 approach`);
  6547. function encode64(data) {
  6548. var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  6549. var PAD = '=';
  6550. var ret = '';
  6551. var leftchar = 0;
  6552. var leftbits = 0;
  6553. for (var i = 0; i < data.length; i++) {
  6554. leftchar = (leftchar << 8) | data[i];
  6555. leftbits += 8;
  6556. while (leftbits >= 6) {
  6557. var curr = (leftchar >> (leftbits-6)) & 0x3f;
  6558. leftbits -= 6;
  6559. ret += BASE[curr];
  6560. }
  6561. }
  6562. if (leftbits == 2) {
  6563. ret += BASE[(leftchar&3) << 4];
  6564. ret += PAD + PAD;
  6565. } else if (leftbits == 4) {
  6566. ret += BASE[(leftchar&0xf) << 2];
  6567. ret += PAD;
  6568. }
  6569. return ret;
  6570. }
  6571. audio.src = 'data:audio/x-' + name.slice(-3) + ';base64,' + encode64(byteArray);
  6572. finish(audio); // we don't wait for confirmation this worked - but it's worth trying
  6573. };
  6574. audio.src = url;
  6575. // workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror
  6576. safeSetTimeout(() => {
  6577. finish(audio); // try to use it even though it is not necessarily ready to play
  6578. }, 10000);
  6579. };
  6580. preloadPlugins.push(audioPlugin);
  6581. // Canvas event setup
  6582. function pointerLockChange() {
  6583. var canvas = Browser.getCanvas();
  6584. Browser.pointerLock = document['pointerLockElement'] === canvas ||
  6585. document['mozPointerLockElement'] === canvas ||
  6586. document['webkitPointerLockElement'] === canvas ||
  6587. document['msPointerLockElement'] === canvas;
  6588. }
  6589. var canvas = Browser.getCanvas();
  6590. if (canvas) {
  6591. // forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module
  6592. // Module['forcedAspectRatio'] = 4 / 3;
  6593. canvas.requestPointerLock = canvas['requestPointerLock'] ||
  6594. canvas['mozRequestPointerLock'] ||
  6595. canvas['webkitRequestPointerLock'] ||
  6596. canvas['msRequestPointerLock'] ||
  6597. (() => {});
  6598. canvas.exitPointerLock = document['exitPointerLock'] ||
  6599. document['mozExitPointerLock'] ||
  6600. document['webkitExitPointerLock'] ||
  6601. document['msExitPointerLock'] ||
  6602. (() => {}); // no-op if function does not exist
  6603. canvas.exitPointerLock = canvas.exitPointerLock.bind(document);
  6604. document.addEventListener('pointerlockchange', pointerLockChange, false);
  6605. document.addEventListener('mozpointerlockchange', pointerLockChange, false);
  6606. document.addEventListener('webkitpointerlockchange', pointerLockChange, false);
  6607. document.addEventListener('mspointerlockchange', pointerLockChange, false);
  6608. if (Module['elementPointerLock']) {
  6609. canvas.addEventListener("click", (ev) => {
  6610. if (!Browser.pointerLock && Browser.getCanvas().requestPointerLock) {
  6611. Browser.getCanvas().requestPointerLock();
  6612. ev.preventDefault();
  6613. }
  6614. }, false);
  6615. }
  6616. }
  6617. },
  6618. createContext(/** @type {HTMLCanvasElement} */ canvas, useWebGL, setInModule, webGLContextAttributes) {
  6619. if (useWebGL && Module['ctx'] && canvas == Browser.getCanvas()) return Module['ctx']; // no need to recreate GL context if it's already been created for this canvas.
  6620. var ctx;
  6621. var contextHandle;
  6622. if (useWebGL) {
  6623. // For GLES2/desktop GL compatibility, adjust a few defaults to be different to WebGL defaults, so that they align better with the desktop defaults.
  6624. var contextAttributes = {
  6625. antialias: false,
  6626. alpha: false,
  6627. majorVersion: 1,
  6628. };
  6629. if (webGLContextAttributes) {
  6630. for (var attribute in webGLContextAttributes) {
  6631. contextAttributes[attribute] = webGLContextAttributes[attribute];
  6632. }
  6633. }
  6634. // 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
  6635. // actually compiled in because application is not doing any GL operations. TODO: Ideally if GL is not being used, this function
  6636. // Browser.createContext() should not even be emitted.
  6637. if (typeof GL != 'undefined') {
  6638. contextHandle = GL.createContext(canvas, contextAttributes);
  6639. if (contextHandle) {
  6640. ctx = GL.getContext(contextHandle).GLctx;
  6641. }
  6642. }
  6643. } else {
  6644. ctx = canvas.getContext('2d');
  6645. }
  6646. if (!ctx) return null;
  6647. if (setInModule) {
  6648. 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');
  6649. Module['ctx'] = ctx;
  6650. if (useWebGL) GL.makeContextCurrent(contextHandle);
  6651. Browser.useWebGL = useWebGL;
  6652. Browser.moduleContextCreatedCallbacks.forEach((callback) => callback());
  6653. Browser.init();
  6654. }
  6655. return ctx;
  6656. },
  6657. fullscreenHandlersInstalled:false,
  6658. lockPointer:undefined,
  6659. resizeCanvas:undefined,
  6660. requestFullscreen(lockPointer, resizeCanvas) {
  6661. Browser.lockPointer = lockPointer;
  6662. Browser.resizeCanvas = resizeCanvas;
  6663. if (typeof Browser.lockPointer == 'undefined') Browser.lockPointer = true;
  6664. if (typeof Browser.resizeCanvas == 'undefined') Browser.resizeCanvas = false;
  6665. var canvas = Browser.getCanvas();
  6666. function fullscreenChange() {
  6667. Browser.isFullscreen = false;
  6668. var canvasContainer = canvas.parentNode;
  6669. if ((document['fullscreenElement'] || document['mozFullScreenElement'] ||
  6670. document['msFullscreenElement'] || document['webkitFullscreenElement'] ||
  6671. document['webkitCurrentFullScreenElement']) === canvasContainer) {
  6672. canvas.exitFullscreen = Browser.exitFullscreen;
  6673. if (Browser.lockPointer) canvas.requestPointerLock();
  6674. Browser.isFullscreen = true;
  6675. if (Browser.resizeCanvas) {
  6676. Browser.setFullscreenCanvasSize();
  6677. } else {
  6678. Browser.updateCanvasDimensions(canvas);
  6679. }
  6680. } else {
  6681. // remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen
  6682. canvasContainer.parentNode.insertBefore(canvas, canvasContainer);
  6683. canvasContainer.parentNode.removeChild(canvasContainer);
  6684. if (Browser.resizeCanvas) {
  6685. Browser.setWindowedCanvasSize();
  6686. } else {
  6687. Browser.updateCanvasDimensions(canvas);
  6688. }
  6689. }
  6690. Module['onFullScreen']?.(Browser.isFullscreen);
  6691. Module['onFullscreen']?.(Browser.isFullscreen);
  6692. }
  6693. if (!Browser.fullscreenHandlersInstalled) {
  6694. Browser.fullscreenHandlersInstalled = true;
  6695. document.addEventListener('fullscreenchange', fullscreenChange, false);
  6696. document.addEventListener('mozfullscreenchange', fullscreenChange, false);
  6697. document.addEventListener('webkitfullscreenchange', fullscreenChange, false);
  6698. document.addEventListener('MSFullscreenChange', fullscreenChange, false);
  6699. }
  6700. // 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
  6701. var canvasContainer = document.createElement("div");
  6702. canvas.parentNode.insertBefore(canvasContainer, canvas);
  6703. canvasContainer.appendChild(canvas);
  6704. // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size)
  6705. canvasContainer.requestFullscreen = canvasContainer['requestFullscreen'] ||
  6706. canvasContainer['mozRequestFullScreen'] ||
  6707. canvasContainer['msRequestFullscreen'] ||
  6708. (canvasContainer['webkitRequestFullscreen'] ? () => canvasContainer['webkitRequestFullscreen'](Element['ALLOW_KEYBOARD_INPUT']) : null) ||
  6709. (canvasContainer['webkitRequestFullScreen'] ? () => canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) : null);
  6710. canvasContainer.requestFullscreen();
  6711. },
  6712. requestFullScreen() {
  6713. abort('Module.requestFullScreen has been replaced by Module.requestFullscreen (without a capital S)');
  6714. },
  6715. exitFullscreen() {
  6716. // This is workaround for chrome. Trying to exit from fullscreen
  6717. // not in fullscreen state will cause "TypeError: Document not active"
  6718. // in chrome. See https://github.com/emscripten-core/emscripten/pull/8236
  6719. if (!Browser.isFullscreen) {
  6720. return false;
  6721. }
  6722. var CFS = document['exitFullscreen'] ||
  6723. document['cancelFullScreen'] ||
  6724. document['mozCancelFullScreen'] ||
  6725. document['msExitFullscreen'] ||
  6726. document['webkitCancelFullScreen'] ||
  6727. (() => {});
  6728. CFS.apply(document, []);
  6729. return true;
  6730. },
  6731. safeSetTimeout(func, timeout) {
  6732. // Legacy function, this is used by the SDL2 port so we need to keep it
  6733. // around at least until that is updated.
  6734. // See https://github.com/libsdl-org/SDL/pull/6304
  6735. return safeSetTimeout(func, timeout);
  6736. },
  6737. getMimetype(name) {
  6738. return {
  6739. 'jpg': 'image/jpeg',
  6740. 'jpeg': 'image/jpeg',
  6741. 'png': 'image/png',
  6742. 'bmp': 'image/bmp',
  6743. 'ogg': 'audio/ogg',
  6744. 'wav': 'audio/wav',
  6745. 'mp3': 'audio/mpeg'
  6746. }[name.slice(name.lastIndexOf('.')+1)];
  6747. },
  6748. getUserMedia(func) {
  6749. window.getUserMedia ||= navigator['getUserMedia'] ||
  6750. navigator['mozGetUserMedia'];
  6751. window.getUserMedia(func);
  6752. },
  6753. getMovementX(event) {
  6754. return event['movementX'] ||
  6755. event['mozMovementX'] ||
  6756. event['webkitMovementX'] ||
  6757. 0;
  6758. },
  6759. getMovementY(event) {
  6760. return event['movementY'] ||
  6761. event['mozMovementY'] ||
  6762. event['webkitMovementY'] ||
  6763. 0;
  6764. },
  6765. getMouseWheelDelta(event) {
  6766. var delta = 0;
  6767. switch (event.type) {
  6768. case 'DOMMouseScroll':
  6769. // 3 lines make up a step
  6770. delta = event.detail / 3;
  6771. break;
  6772. case 'mousewheel':
  6773. // 120 units make up a step
  6774. delta = event.wheelDelta / 120;
  6775. break;
  6776. case 'wheel':
  6777. delta = event.deltaY
  6778. switch (event.deltaMode) {
  6779. case 0:
  6780. // DOM_DELTA_PIXEL: 100 pixels make up a step
  6781. delta /= 100;
  6782. break;
  6783. case 1:
  6784. // DOM_DELTA_LINE: 3 lines make up a step
  6785. delta /= 3;
  6786. break;
  6787. case 2:
  6788. // DOM_DELTA_PAGE: A page makes up 80 steps
  6789. delta *= 80;
  6790. break;
  6791. default:
  6792. throw 'unrecognized mouse wheel delta mode: ' + event.deltaMode;
  6793. }
  6794. break;
  6795. default:
  6796. throw 'unrecognized mouse wheel event: ' + event.type;
  6797. }
  6798. return delta;
  6799. },
  6800. mouseX:0,
  6801. mouseY:0,
  6802. mouseMovementX:0,
  6803. mouseMovementY:0,
  6804. touches:{
  6805. },
  6806. lastTouches:{
  6807. },
  6808. calculateMouseCoords(pageX, pageY) {
  6809. // Calculate the movement based on the changes
  6810. // in the coordinates.
  6811. var canvas = Browser.getCanvas();
  6812. var rect = canvas.getBoundingClientRect();
  6813. // Neither .scrollX or .pageXOffset are defined in a spec, but
  6814. // we prefer .scrollX because it is currently in a spec draft.
  6815. // (see: http://www.w3.org/TR/2013/WD-cssom-view-20131217/)
  6816. var scrollX = ((typeof window.scrollX != 'undefined') ? window.scrollX : window.pageXOffset);
  6817. var scrollY = ((typeof window.scrollY != 'undefined') ? window.scrollY : window.pageYOffset);
  6818. // If this assert lands, it's likely because the browser doesn't support scrollX or pageXOffset
  6819. // and we have no viable fallback.
  6820. assert((typeof scrollX != 'undefined') && (typeof scrollY != 'undefined'), 'Unable to retrieve scroll position, mouse positions likely broken.');
  6821. var adjustedX = pageX - (scrollX + rect.left);
  6822. var adjustedY = pageY - (scrollY + rect.top);
  6823. // the canvas might be CSS-scaled compared to its backbuffer;
  6824. // SDL-using content will want mouse coordinates in terms
  6825. // of backbuffer units.
  6826. adjustedX = adjustedX * (canvas.width / rect.width);
  6827. adjustedY = adjustedY * (canvas.height / rect.height);
  6828. return { x: adjustedX, y: adjustedY };
  6829. },
  6830. setMouseCoords(pageX, pageY) {
  6831. const {x, y} = Browser.calculateMouseCoords(pageX, pageY);
  6832. Browser.mouseMovementX = x - Browser.mouseX;
  6833. Browser.mouseMovementY = y - Browser.mouseY;
  6834. Browser.mouseX = x;
  6835. Browser.mouseY = y;
  6836. },
  6837. calculateMouseEvent(event) { // event should be mousemove, mousedown or mouseup
  6838. if (Browser.pointerLock) {
  6839. // When the pointer is locked, calculate the coordinates
  6840. // based on the movement of the mouse.
  6841. // Workaround for Firefox bug 764498
  6842. if (event.type != 'mousemove' &&
  6843. ('mozMovementX' in event)) {
  6844. Browser.mouseMovementX = Browser.mouseMovementY = 0;
  6845. } else {
  6846. Browser.mouseMovementX = Browser.getMovementX(event);
  6847. Browser.mouseMovementY = Browser.getMovementY(event);
  6848. }
  6849. // add the mouse delta to the current absolute mouse position
  6850. Browser.mouseX += Browser.mouseMovementX;
  6851. Browser.mouseY += Browser.mouseMovementY;
  6852. } else {
  6853. if (event.type === 'touchstart' || event.type === 'touchend' || event.type === 'touchmove') {
  6854. var touch = event.touch;
  6855. if (touch === undefined) {
  6856. return; // the "touch" property is only defined in SDL
  6857. }
  6858. var coords = Browser.calculateMouseCoords(touch.pageX, touch.pageY);
  6859. if (event.type === 'touchstart') {
  6860. Browser.lastTouches[touch.identifier] = coords;
  6861. Browser.touches[touch.identifier] = coords;
  6862. } else if (event.type === 'touchend' || event.type === 'touchmove') {
  6863. var last = Browser.touches[touch.identifier];
  6864. last ||= coords;
  6865. Browser.lastTouches[touch.identifier] = last;
  6866. Browser.touches[touch.identifier] = coords;
  6867. }
  6868. return;
  6869. }
  6870. Browser.setMouseCoords(event.pageX, event.pageY);
  6871. }
  6872. },
  6873. resizeListeners:[],
  6874. updateResizeListeners() {
  6875. var canvas = Browser.getCanvas();
  6876. Browser.resizeListeners.forEach((listener) => listener(canvas.width, canvas.height));
  6877. },
  6878. setCanvasSize(width, height, noUpdates) {
  6879. var canvas = Browser.getCanvas();
  6880. Browser.updateCanvasDimensions(canvas, width, height);
  6881. if (!noUpdates) Browser.updateResizeListeners();
  6882. },
  6883. windowedWidth:0,
  6884. windowedHeight:0,
  6885. setFullscreenCanvasSize() {
  6886. // check if SDL is available
  6887. if (typeof SDL != "undefined") {
  6888. var flags = HEAPU32[((SDL.screen)>>2)];
  6889. flags = flags | 0x00800000; // set SDL_FULLSCREEN flag
  6890. HEAP32[((SDL.screen)>>2)] = flags;
  6891. }
  6892. Browser.updateCanvasDimensions(Browser.getCanvas());
  6893. Browser.updateResizeListeners();
  6894. },
  6895. setWindowedCanvasSize() {
  6896. // check if SDL is available
  6897. if (typeof SDL != "undefined") {
  6898. var flags = HEAPU32[((SDL.screen)>>2)];
  6899. flags = flags & ~0x00800000; // clear SDL_FULLSCREEN flag
  6900. HEAP32[((SDL.screen)>>2)] = flags;
  6901. }
  6902. Browser.updateCanvasDimensions(Browser.getCanvas());
  6903. Browser.updateResizeListeners();
  6904. },
  6905. updateCanvasDimensions(canvas, wNative, hNative) {
  6906. if (wNative && hNative) {
  6907. canvas.widthNative = wNative;
  6908. canvas.heightNative = hNative;
  6909. } else {
  6910. wNative = canvas.widthNative;
  6911. hNative = canvas.heightNative;
  6912. }
  6913. var w = wNative;
  6914. var h = hNative;
  6915. if (Module['forcedAspectRatio'] > 0) {
  6916. if (w/h < Module['forcedAspectRatio']) {
  6917. w = Math.round(h * Module['forcedAspectRatio']);
  6918. } else {
  6919. h = Math.round(w / Module['forcedAspectRatio']);
  6920. }
  6921. }
  6922. if (((document['fullscreenElement'] || document['mozFullScreenElement'] ||
  6923. document['msFullscreenElement'] || document['webkitFullscreenElement'] ||
  6924. document['webkitCurrentFullScreenElement']) === canvas.parentNode) && (typeof screen != 'undefined')) {
  6925. var factor = Math.min(screen.width / w, screen.height / h);
  6926. w = Math.round(w * factor);
  6927. h = Math.round(h * factor);
  6928. }
  6929. if (Browser.resizeCanvas) {
  6930. if (canvas.width != w) canvas.width = w;
  6931. if (canvas.height != h) canvas.height = h;
  6932. if (typeof canvas.style != 'undefined') {
  6933. canvas.style.removeProperty( "width");
  6934. canvas.style.removeProperty("height");
  6935. }
  6936. } else {
  6937. if (canvas.width != wNative) canvas.width = wNative;
  6938. if (canvas.height != hNative) canvas.height = hNative;
  6939. if (typeof canvas.style != 'undefined') {
  6940. if (w != wNative || h != hNative) {
  6941. canvas.style.setProperty( "width", w + "px", "important");
  6942. canvas.style.setProperty("height", h + "px", "important");
  6943. } else {
  6944. canvas.style.removeProperty( "width");
  6945. canvas.style.removeProperty("height");
  6946. }
  6947. }
  6948. }
  6949. },
  6950. };
  6951. var _emscripten_set_window_title = (title) => document.title = UTF8ToString(title);
  6952. function _fd_close(fd) {
  6953. try {
  6954. var stream = SYSCALLS.getStreamFromFD(fd);
  6955. FS.close(stream);
  6956. return 0;
  6957. } catch (e) {
  6958. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  6959. return e.errno;
  6960. }
  6961. }
  6962. /** @param {number=} offset */
  6963. var doReadv = (stream, iov, iovcnt, offset) => {
  6964. var ret = 0;
  6965. for (var i = 0; i < iovcnt; i++) {
  6966. var ptr = HEAPU32[((iov)>>2)];
  6967. var len = HEAPU32[(((iov)+(4))>>2)];
  6968. iov += 8;
  6969. var curr = FS.read(stream, HEAP8, ptr, len, offset);
  6970. if (curr < 0) return -1;
  6971. ret += curr;
  6972. if (curr < len) break; // nothing more to read
  6973. if (typeof offset != 'undefined') {
  6974. offset += curr;
  6975. }
  6976. }
  6977. return ret;
  6978. };
  6979. function _fd_read(fd, iov, iovcnt, pnum) {
  6980. try {
  6981. var stream = SYSCALLS.getStreamFromFD(fd);
  6982. var num = doReadv(stream, iov, iovcnt);
  6983. HEAPU32[((pnum)>>2)] = num;
  6984. return 0;
  6985. } catch (e) {
  6986. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  6987. return e.errno;
  6988. }
  6989. }
  6990. function _fd_seek(fd, offset, whence, newOffset) {
  6991. offset = bigintToI53Checked(offset);
  6992. try {
  6993. if (isNaN(offset)) return 61;
  6994. var stream = SYSCALLS.getStreamFromFD(fd);
  6995. FS.llseek(stream, offset, whence);
  6996. HEAP64[((newOffset)>>3)] = BigInt(stream.position);
  6997. if (stream.getdents && offset === 0 && whence === 0) stream.getdents = null; // reset readdir state
  6998. return 0;
  6999. } catch (e) {
  7000. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  7001. return e.errno;
  7002. }
  7003. ;
  7004. }
  7005. /** @param {number=} offset */
  7006. var doWritev = (stream, iov, iovcnt, offset) => {
  7007. var ret = 0;
  7008. for (var i = 0; i < iovcnt; i++) {
  7009. var ptr = HEAPU32[((iov)>>2)];
  7010. var len = HEAPU32[(((iov)+(4))>>2)];
  7011. iov += 8;
  7012. var curr = FS.write(stream, HEAP8, ptr, len, offset);
  7013. if (curr < 0) return -1;
  7014. ret += curr;
  7015. if (curr < len) {
  7016. // No more space to write.
  7017. break;
  7018. }
  7019. if (typeof offset != 'undefined') {
  7020. offset += curr;
  7021. }
  7022. }
  7023. return ret;
  7024. };
  7025. function _fd_write(fd, iov, iovcnt, pnum) {
  7026. try {
  7027. var stream = SYSCALLS.getStreamFromFD(fd);
  7028. var num = doWritev(stream, iov, iovcnt);
  7029. HEAPU32[((pnum)>>2)] = num;
  7030. return 0;
  7031. } catch (e) {
  7032. if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
  7033. return e.errno;
  7034. }
  7035. }
  7036. /** @constructor */
  7037. function GLFW_Window(id, width, height, framebufferWidth, framebufferHeight, title, monitor, share) {
  7038. this.id = id;
  7039. this.x = 0;
  7040. this.y = 0;
  7041. this.fullscreen = false; // Used to determine if app in fullscreen mode
  7042. this.storedX = 0; // Used to store X before fullscreen
  7043. this.storedY = 0; // Used to store Y before fullscreen
  7044. this.width = width;
  7045. this.height = height;
  7046. this.framebufferWidth = framebufferWidth;
  7047. this.framebufferHeight = framebufferHeight;
  7048. this.storedWidth = width; // Used to store width before fullscreen
  7049. this.storedHeight = height; // Used to store height before fullscreen
  7050. this.title = title;
  7051. this.monitor = monitor;
  7052. this.share = share;
  7053. this.attributes = Object.assign({}, GLFW.hints);
  7054. this.inputModes = {
  7055. 0x00033001:0x00034001, // GLFW_CURSOR (GLFW_CURSOR_NORMAL)
  7056. 0x00033002:0, // GLFW_STICKY_KEYS
  7057. 0x00033003:0, // GLFW_STICKY_MOUSE_BUTTONS
  7058. };
  7059. this.buttons = 0;
  7060. this.keys = new Array();
  7061. this.domKeys = new Array();
  7062. this.shouldClose = 0;
  7063. this.title = null;
  7064. this.windowPosFunc = 0; // GLFWwindowposfun
  7065. this.windowSizeFunc = 0; // GLFWwindowsizefun
  7066. this.windowCloseFunc = 0; // GLFWwindowclosefun
  7067. this.windowRefreshFunc = 0; // GLFWwindowrefreshfun
  7068. this.windowFocusFunc = 0; // GLFWwindowfocusfun
  7069. this.windowIconifyFunc = 0; // GLFWwindowiconifyfun
  7070. this.windowMaximizeFunc = 0; // GLFWwindowmaximizefun
  7071. this.framebufferSizeFunc = 0; // GLFWframebuffersizefun
  7072. this.windowContentScaleFunc = 0; // GLFWwindowcontentscalefun
  7073. this.mouseButtonFunc = 0; // GLFWmousebuttonfun
  7074. this.cursorPosFunc = 0; // GLFWcursorposfun
  7075. this.cursorEnterFunc = 0; // GLFWcursorenterfun
  7076. this.scrollFunc = 0; // GLFWscrollfun
  7077. this.dropFunc = 0; // GLFWdropfun
  7078. this.keyFunc = 0; // GLFWkeyfun
  7079. this.charFunc = 0; // GLFWcharfun
  7080. this.userptr = 0;
  7081. }
  7082. var GLFW = {
  7083. WindowFromId:(id) => {
  7084. if (id <= 0 || !GLFW.windows) return null;
  7085. return GLFW.windows[id - 1];
  7086. },
  7087. joystickFunc:0,
  7088. errorFunc:0,
  7089. monitorFunc:0,
  7090. active:null,
  7091. scale:null,
  7092. windows:null,
  7093. monitors:null,
  7094. monitorString:null,
  7095. versionString:null,
  7096. initialTime:null,
  7097. extensions:null,
  7098. devicePixelRatioMQL:null,
  7099. hints:null,
  7100. primaryTouchId:null,
  7101. defaultHints:{
  7102. 131073:0,
  7103. 131074:0,
  7104. 131075:1,
  7105. 131076:1,
  7106. 131077:1,
  7107. 131082:0,
  7108. 135169:8,
  7109. 135170:8,
  7110. 135171:8,
  7111. 135172:8,
  7112. 135173:24,
  7113. 135174:8,
  7114. 135175:0,
  7115. 135176:0,
  7116. 135177:0,
  7117. 135178:0,
  7118. 135179:0,
  7119. 135180:0,
  7120. 135181:0,
  7121. 135182:0,
  7122. 135183:0,
  7123. 139265:196609,
  7124. 139266:1,
  7125. 139267:0,
  7126. 139268:0,
  7127. 139269:0,
  7128. 139270:0,
  7129. 139271:0,
  7130. 139272:0,
  7131. 139276:0,
  7132. },
  7133. DOMToGLFWKeyCode:(keycode) => {
  7134. switch (keycode) {
  7135. // these keycodes are only defined for GLFW3, assume they are the same for GLFW2
  7136. case 0x20:return 32; // DOM_VK_SPACE -> GLFW_KEY_SPACE
  7137. case 0xDE:return 39; // DOM_VK_QUOTE -> GLFW_KEY_APOSTROPHE
  7138. case 0xBC:return 44; // DOM_VK_COMMA -> GLFW_KEY_COMMA
  7139. case 0xAD:return 45; // DOM_VK_HYPHEN_MINUS -> GLFW_KEY_MINUS
  7140. case 0xBD:return 45; // DOM_VK_MINUS -> GLFW_KEY_MINUS
  7141. case 0xBE:return 46; // DOM_VK_PERIOD -> GLFW_KEY_PERIOD
  7142. case 0xBF:return 47; // DOM_VK_SLASH -> GLFW_KEY_SLASH
  7143. case 0x30:return 48; // DOM_VK_0 -> GLFW_KEY_0
  7144. case 0x31:return 49; // DOM_VK_1 -> GLFW_KEY_1
  7145. case 0x32:return 50; // DOM_VK_2 -> GLFW_KEY_2
  7146. case 0x33:return 51; // DOM_VK_3 -> GLFW_KEY_3
  7147. case 0x34:return 52; // DOM_VK_4 -> GLFW_KEY_4
  7148. case 0x35:return 53; // DOM_VK_5 -> GLFW_KEY_5
  7149. case 0x36:return 54; // DOM_VK_6 -> GLFW_KEY_6
  7150. case 0x37:return 55; // DOM_VK_7 -> GLFW_KEY_7
  7151. case 0x38:return 56; // DOM_VK_8 -> GLFW_KEY_8
  7152. case 0x39:return 57; // DOM_VK_9 -> GLFW_KEY_9
  7153. case 0x3B:return 59; // DOM_VK_SEMICOLON -> GLFW_KEY_SEMICOLON
  7154. case 0x3D:return 61; // DOM_VK_EQUALS -> GLFW_KEY_EQUAL
  7155. case 0xBB:return 61; // DOM_VK_EQUALS -> GLFW_KEY_EQUAL
  7156. case 0x41:return 65; // DOM_VK_A -> GLFW_KEY_A
  7157. case 0x42:return 66; // DOM_VK_B -> GLFW_KEY_B
  7158. case 0x43:return 67; // DOM_VK_C -> GLFW_KEY_C
  7159. case 0x44:return 68; // DOM_VK_D -> GLFW_KEY_D
  7160. case 0x45:return 69; // DOM_VK_E -> GLFW_KEY_E
  7161. case 0x46:return 70; // DOM_VK_F -> GLFW_KEY_F
  7162. case 0x47:return 71; // DOM_VK_G -> GLFW_KEY_G
  7163. case 0x48:return 72; // DOM_VK_H -> GLFW_KEY_H
  7164. case 0x49:return 73; // DOM_VK_I -> GLFW_KEY_I
  7165. case 0x4A:return 74; // DOM_VK_J -> GLFW_KEY_J
  7166. case 0x4B:return 75; // DOM_VK_K -> GLFW_KEY_K
  7167. case 0x4C:return 76; // DOM_VK_L -> GLFW_KEY_L
  7168. case 0x4D:return 77; // DOM_VK_M -> GLFW_KEY_M
  7169. case 0x4E:return 78; // DOM_VK_N -> GLFW_KEY_N
  7170. case 0x4F:return 79; // DOM_VK_O -> GLFW_KEY_O
  7171. case 0x50:return 80; // DOM_VK_P -> GLFW_KEY_P
  7172. case 0x51:return 81; // DOM_VK_Q -> GLFW_KEY_Q
  7173. case 0x52:return 82; // DOM_VK_R -> GLFW_KEY_R
  7174. case 0x53:return 83; // DOM_VK_S -> GLFW_KEY_S
  7175. case 0x54:return 84; // DOM_VK_T -> GLFW_KEY_T
  7176. case 0x55:return 85; // DOM_VK_U -> GLFW_KEY_U
  7177. case 0x56:return 86; // DOM_VK_V -> GLFW_KEY_V
  7178. case 0x57:return 87; // DOM_VK_W -> GLFW_KEY_W
  7179. case 0x58:return 88; // DOM_VK_X -> GLFW_KEY_X
  7180. case 0x59:return 89; // DOM_VK_Y -> GLFW_KEY_Y
  7181. case 0x5a:return 90; // DOM_VK_Z -> GLFW_KEY_Z
  7182. case 0xDB:return 91; // DOM_VK_OPEN_BRACKET -> GLFW_KEY_LEFT_BRACKET
  7183. case 0xDC:return 92; // DOM_VK_BACKSLASH -> GLFW_KEY_BACKSLASH
  7184. case 0xDD:return 93; // DOM_VK_CLOSE_BRACKET -> GLFW_KEY_RIGHT_BRACKET
  7185. case 0xC0:return 96; // DOM_VK_BACK_QUOTE -> GLFW_KEY_GRAVE_ACCENT
  7186. case 0x1B:return 256; // DOM_VK_ESCAPE -> GLFW_KEY_ESCAPE
  7187. case 0x0D:return 257; // DOM_VK_RETURN -> GLFW_KEY_ENTER
  7188. case 0x09:return 258; // DOM_VK_TAB -> GLFW_KEY_TAB
  7189. case 0x08:return 259; // DOM_VK_BACK -> GLFW_KEY_BACKSPACE
  7190. case 0x2D:return 260; // DOM_VK_INSERT -> GLFW_KEY_INSERT
  7191. case 0x2E:return 261; // DOM_VK_DELETE -> GLFW_KEY_DELETE
  7192. case 0x27:return 262; // DOM_VK_RIGHT -> GLFW_KEY_RIGHT
  7193. case 0x25:return 263; // DOM_VK_LEFT -> GLFW_KEY_LEFT
  7194. case 0x28:return 264; // DOM_VK_DOWN -> GLFW_KEY_DOWN
  7195. case 0x26:return 265; // DOM_VK_UP -> GLFW_KEY_UP
  7196. case 0x21:return 266; // DOM_VK_PAGE_UP -> GLFW_KEY_PAGE_UP
  7197. case 0x22:return 267; // DOM_VK_PAGE_DOWN -> GLFW_KEY_PAGE_DOWN
  7198. case 0x24:return 268; // DOM_VK_HOME -> GLFW_KEY_HOME
  7199. case 0x23:return 269; // DOM_VK_END -> GLFW_KEY_END
  7200. case 0x14:return 280; // DOM_VK_CAPS_LOCK -> GLFW_KEY_CAPS_LOCK
  7201. case 0x91:return 281; // DOM_VK_SCROLL_LOCK -> GLFW_KEY_SCROLL_LOCK
  7202. case 0x90:return 282; // DOM_VK_NUM_LOCK -> GLFW_KEY_NUM_LOCK
  7203. case 0x2C:return 283; // DOM_VK_SNAPSHOT -> GLFW_KEY_PRINT_SCREEN
  7204. case 0x13:return 284; // DOM_VK_PAUSE -> GLFW_KEY_PAUSE
  7205. case 0x70:return 290; // DOM_VK_F1 -> GLFW_KEY_F1
  7206. case 0x71:return 291; // DOM_VK_F2 -> GLFW_KEY_F2
  7207. case 0x72:return 292; // DOM_VK_F3 -> GLFW_KEY_F3
  7208. case 0x73:return 293; // DOM_VK_F4 -> GLFW_KEY_F4
  7209. case 0x74:return 294; // DOM_VK_F5 -> GLFW_KEY_F5
  7210. case 0x75:return 295; // DOM_VK_F6 -> GLFW_KEY_F6
  7211. case 0x76:return 296; // DOM_VK_F7 -> GLFW_KEY_F7
  7212. case 0x77:return 297; // DOM_VK_F8 -> GLFW_KEY_F8
  7213. case 0x78:return 298; // DOM_VK_F9 -> GLFW_KEY_F9
  7214. case 0x79:return 299; // DOM_VK_F10 -> GLFW_KEY_F10
  7215. case 0x7A:return 300; // DOM_VK_F11 -> GLFW_KEY_F11
  7216. case 0x7B:return 301; // DOM_VK_F12 -> GLFW_KEY_F12
  7217. case 0x7C:return 302; // DOM_VK_F13 -> GLFW_KEY_F13
  7218. case 0x7D:return 303; // DOM_VK_F14 -> GLFW_KEY_F14
  7219. case 0x7E:return 304; // DOM_VK_F15 -> GLFW_KEY_F15
  7220. case 0x7F:return 305; // DOM_VK_F16 -> GLFW_KEY_F16
  7221. case 0x80:return 306; // DOM_VK_F17 -> GLFW_KEY_F17
  7222. case 0x81:return 307; // DOM_VK_F18 -> GLFW_KEY_F18
  7223. case 0x82:return 308; // DOM_VK_F19 -> GLFW_KEY_F19
  7224. case 0x83:return 309; // DOM_VK_F20 -> GLFW_KEY_F20
  7225. case 0x84:return 310; // DOM_VK_F21 -> GLFW_KEY_F21
  7226. case 0x85:return 311; // DOM_VK_F22 -> GLFW_KEY_F22
  7227. case 0x86:return 312; // DOM_VK_F23 -> GLFW_KEY_F23
  7228. case 0x87:return 313; // DOM_VK_F24 -> GLFW_KEY_F24
  7229. case 0x88:return 314; // 0x88 (not used?) -> GLFW_KEY_F25
  7230. case 0x60:return 320; // DOM_VK_NUMPAD0 -> GLFW_KEY_KP_0
  7231. case 0x61:return 321; // DOM_VK_NUMPAD1 -> GLFW_KEY_KP_1
  7232. case 0x62:return 322; // DOM_VK_NUMPAD2 -> GLFW_KEY_KP_2
  7233. case 0x63:return 323; // DOM_VK_NUMPAD3 -> GLFW_KEY_KP_3
  7234. case 0x64:return 324; // DOM_VK_NUMPAD4 -> GLFW_KEY_KP_4
  7235. case 0x65:return 325; // DOM_VK_NUMPAD5 -> GLFW_KEY_KP_5
  7236. case 0x66:return 326; // DOM_VK_NUMPAD6 -> GLFW_KEY_KP_6
  7237. case 0x67:return 327; // DOM_VK_NUMPAD7 -> GLFW_KEY_KP_7
  7238. case 0x68:return 328; // DOM_VK_NUMPAD8 -> GLFW_KEY_KP_8
  7239. case 0x69:return 329; // DOM_VK_NUMPAD9 -> GLFW_KEY_KP_9
  7240. case 0x6E:return 330; // DOM_VK_DECIMAL -> GLFW_KEY_KP_DECIMAL
  7241. case 0x6F:return 331; // DOM_VK_DIVIDE -> GLFW_KEY_KP_DIVIDE
  7242. case 0x6A:return 332; // DOM_VK_MULTIPLY -> GLFW_KEY_KP_MULTIPLY
  7243. case 0x6D:return 333; // DOM_VK_SUBTRACT -> GLFW_KEY_KP_SUBTRACT
  7244. case 0x6B:return 334; // DOM_VK_ADD -> GLFW_KEY_KP_ADD
  7245. // case 0x0D:return 335; // DOM_VK_RETURN -> GLFW_KEY_KP_ENTER (DOM_KEY_LOCATION_RIGHT)
  7246. // case 0x61:return 336; // DOM_VK_EQUALS -> GLFW_KEY_KP_EQUAL (DOM_KEY_LOCATION_RIGHT)
  7247. case 0x10:return 340; // DOM_VK_SHIFT -> GLFW_KEY_LEFT_SHIFT
  7248. case 0x11:return 341; // DOM_VK_CONTROL -> GLFW_KEY_LEFT_CONTROL
  7249. case 0x12:return 342; // DOM_VK_ALT -> GLFW_KEY_LEFT_ALT
  7250. case 0x5B:return 343; // DOM_VK_WIN -> GLFW_KEY_LEFT_SUPER
  7251. case 0xE0:return 343; // DOM_VK_META -> GLFW_KEY_LEFT_SUPER
  7252. // case 0x10:return 344; // DOM_VK_SHIFT -> GLFW_KEY_RIGHT_SHIFT (DOM_KEY_LOCATION_RIGHT)
  7253. // case 0x11:return 345; // DOM_VK_CONTROL -> GLFW_KEY_RIGHT_CONTROL (DOM_KEY_LOCATION_RIGHT)
  7254. // case 0x12:return 346; // DOM_VK_ALT -> GLFW_KEY_RIGHT_ALT (DOM_KEY_LOCATION_RIGHT)
  7255. // case 0x5B:return 347; // DOM_VK_WIN -> GLFW_KEY_RIGHT_SUPER (DOM_KEY_LOCATION_RIGHT)
  7256. case 0x5D:return 348; // DOM_VK_CONTEXT_MENU -> GLFW_KEY_MENU
  7257. // XXX: GLFW_KEY_WORLD_1, GLFW_KEY_WORLD_2 what are these?
  7258. default:return -1; // GLFW_KEY_UNKNOWN
  7259. };
  7260. },
  7261. getModBits:(win) => {
  7262. var mod = 0;
  7263. if (win.keys[340]) mod |= 0x0001; // GLFW_MOD_SHIFT
  7264. if (win.keys[341]) mod |= 0x0002; // GLFW_MOD_CONTROL
  7265. if (win.keys[342]) mod |= 0x0004; // GLFW_MOD_ALT
  7266. if (win.keys[343] || win.keys[348]) mod |= 0x0008; // GLFW_MOD_SUPER
  7267. // add caps and num lock keys? only if lock_key_mod is set
  7268. return mod;
  7269. },
  7270. onKeyPress:(event) => {
  7271. if (!GLFW.active || !GLFW.active.charFunc) return;
  7272. if (event.ctrlKey || event.metaKey) return;
  7273. // correct unicode charCode is only available with onKeyPress event
  7274. var charCode = event.charCode;
  7275. if (charCode == 0 || (charCode >= 0x00 && charCode <= 0x1F)) return;
  7276. getWasmTableEntry(GLFW.active.charFunc)(GLFW.active.id, charCode);
  7277. },
  7278. onKeyChanged:(keyCode, status) => {
  7279. if (!GLFW.active) return;
  7280. var key = GLFW.DOMToGLFWKeyCode(keyCode);
  7281. if (key == -1) return;
  7282. var repeat = status && GLFW.active.keys[key];
  7283. GLFW.active.keys[key] = status;
  7284. GLFW.active.domKeys[keyCode] = status;
  7285. if (GLFW.active.keyFunc) {
  7286. if (repeat) status = 2; // GLFW_REPEAT
  7287. getWasmTableEntry(GLFW.active.keyFunc)(GLFW.active.id, key, keyCode, status, GLFW.getModBits(GLFW.active));
  7288. }
  7289. },
  7290. onGamepadConnected:(event) => {
  7291. GLFW.refreshJoysticks();
  7292. },
  7293. onGamepadDisconnected:(event) => {
  7294. GLFW.refreshJoysticks();
  7295. },
  7296. onKeydown:(event) => {
  7297. GLFW.onKeyChanged(event.keyCode, 1); // GLFW_PRESS or GLFW_REPEAT
  7298. // This logic comes directly from the sdl implementation. We cannot
  7299. // call preventDefault on all keydown events otherwise onKeyPress will
  7300. // not get called
  7301. if (event.key == 'Backspace' || event.key == 'Tab') {
  7302. event.preventDefault();
  7303. }
  7304. },
  7305. onKeyup:(event) => {
  7306. GLFW.onKeyChanged(event.keyCode, 0); // GLFW_RELEASE
  7307. },
  7308. onBlur:(event) => {
  7309. if (!GLFW.active) return;
  7310. for (var i = 0; i < GLFW.active.domKeys.length; ++i) {
  7311. if (GLFW.active.domKeys[i]) {
  7312. GLFW.onKeyChanged(i, 0); // GLFW_RELEASE
  7313. }
  7314. }
  7315. },
  7316. onMousemove:(event) => {
  7317. if (!GLFW.active) return;
  7318. if (event.type === 'touchmove') {
  7319. // Handling for touch events that are being converted to mouse input.
  7320. // Don't let the browser fire a duplicate mouse event.
  7321. event.preventDefault();
  7322. let primaryChanged = false;
  7323. for (let i of event.changedTouches) {
  7324. // If our chosen primary touch moved, update Browser mouse coords
  7325. if (GLFW.primaryTouchId === i.identifier) {
  7326. Browser.setMouseCoords(i.pageX, i.pageY);
  7327. primaryChanged = true;
  7328. break;
  7329. }
  7330. }
  7331. if (!primaryChanged) {
  7332. // Do not send mouse events if some touch other than the primary triggered this.
  7333. return;
  7334. }
  7335. } else {
  7336. // Handling for non-touch mouse input events.
  7337. Browser.calculateMouseEvent(event);
  7338. }
  7339. if (event.target != Browser.getCanvas() || !GLFW.active.cursorPosFunc) return;
  7340. if (GLFW.active.cursorPosFunc) {
  7341. getWasmTableEntry(GLFW.active.cursorPosFunc)(GLFW.active.id, Browser.mouseX, Browser.mouseY);
  7342. }
  7343. },
  7344. DOMToGLFWMouseButton:(event) => {
  7345. // DOM and glfw have different button codes.
  7346. // See http://www.w3schools.com/jsref/event_button.asp.
  7347. var eventButton = event['button'];
  7348. if (eventButton > 0) {
  7349. if (eventButton == 1) {
  7350. eventButton = 2;
  7351. } else {
  7352. eventButton = 1;
  7353. }
  7354. }
  7355. return eventButton;
  7356. },
  7357. onMouseenter:(event) => {
  7358. if (!GLFW.active) return;
  7359. if (event.target != Browser.getCanvas()) return;
  7360. if (GLFW.active.cursorEnterFunc) {
  7361. getWasmTableEntry(GLFW.active.cursorEnterFunc)(GLFW.active.id, 1);
  7362. }
  7363. },
  7364. onMouseleave:(event) => {
  7365. if (!GLFW.active) return;
  7366. if (event.target != Browser.getCanvas()) return;
  7367. if (GLFW.active.cursorEnterFunc) {
  7368. getWasmTableEntry(GLFW.active.cursorEnterFunc)(GLFW.active.id, 0);
  7369. }
  7370. },
  7371. onMouseButtonChanged:(event, status) => {
  7372. if (!GLFW.active) return;
  7373. if (event.target != Browser.getCanvas()) return;
  7374. // Is this from a touch event?
  7375. const isTouchType = event.type === 'touchstart' || event.type === 'touchend' || event.type === 'touchcancel';
  7376. // Only emulating mouse left-click behavior for touches.
  7377. let eventButton = 0;
  7378. if (isTouchType) {
  7379. // Handling for touch events that are being converted to mouse input.
  7380. // Don't let the browser fire a duplicate mouse event.
  7381. event.preventDefault();
  7382. let primaryChanged = false;
  7383. // Set a primary touch if we have none.
  7384. if (GLFW.primaryTouchId === null && event.type === 'touchstart' && event.targetTouches.length > 0) {
  7385. // Pick the first touch that started in the canvas and treat it as primary.
  7386. const chosenTouch = event.targetTouches[0];
  7387. GLFW.primaryTouchId = chosenTouch.identifier;
  7388. Browser.setMouseCoords(chosenTouch.pageX, chosenTouch.pageY);
  7389. primaryChanged = true;
  7390. } else if (event.type === 'touchend' || event.type === 'touchcancel') {
  7391. // Clear the primary touch if it ended.
  7392. for (let i of event.changedTouches) {
  7393. // If our chosen primary touch ended, remove it.
  7394. if (GLFW.primaryTouchId === i.identifier) {
  7395. GLFW.primaryTouchId = null;
  7396. primaryChanged = true;
  7397. break;
  7398. }
  7399. }
  7400. }
  7401. if (!primaryChanged) {
  7402. // Do not send mouse events if some touch other than the primary triggered this.
  7403. return;
  7404. }
  7405. } else {
  7406. // Handling for non-touch mouse input events.
  7407. Browser.calculateMouseEvent(event);
  7408. eventButton = GLFW.DOMToGLFWMouseButton(event);
  7409. }
  7410. if (status == 1) { // GLFW_PRESS
  7411. GLFW.active.buttons |= (1 << eventButton);
  7412. try {
  7413. event.target.setCapture();
  7414. } catch (e) {}
  7415. } else { // GLFW_RELEASE
  7416. GLFW.active.buttons &= ~(1 << eventButton);
  7417. }
  7418. // Send mouse event to GLFW.
  7419. if (GLFW.active.mouseButtonFunc) {
  7420. getWasmTableEntry(GLFW.active.mouseButtonFunc)(GLFW.active.id, eventButton, status, GLFW.getModBits(GLFW.active));
  7421. }
  7422. },
  7423. onMouseButtonDown:(event) => {
  7424. if (!GLFW.active) return;
  7425. GLFW.onMouseButtonChanged(event, 1); // GLFW_PRESS
  7426. },
  7427. onMouseButtonUp:(event) => {
  7428. if (!GLFW.active) return;
  7429. GLFW.onMouseButtonChanged(event, 0); // GLFW_RELEASE
  7430. },
  7431. onMouseWheel:(event) => {
  7432. // Note the minus sign that flips browser wheel direction (positive direction scrolls page down) to native wheel direction (positive direction is mouse wheel up)
  7433. var delta = -Browser.getMouseWheelDelta(event);
  7434. delta = (delta == 0) ? 0 : (delta > 0 ? Math.max(delta, 1) : Math.min(delta, -1)); // Quantize to integer so that minimum scroll is at least +/- 1.
  7435. GLFW.wheelPos += delta;
  7436. if (!GLFW.active || !GLFW.active.scrollFunc || event.target != Browser.getCanvas()) return;
  7437. var sx = 0;
  7438. var sy = delta;
  7439. if (event.type == 'mousewheel') {
  7440. sx = event.wheelDeltaX;
  7441. } else {
  7442. sx = event.deltaX;
  7443. }
  7444. getWasmTableEntry(GLFW.active.scrollFunc)(GLFW.active.id, sx, sy);
  7445. event.preventDefault();
  7446. },
  7447. onCanvasResize:(width, height, framebufferWidth, framebufferHeight) => {
  7448. if (!GLFW.active) return;
  7449. var resizeNeeded = false;
  7450. // If the client is requesting fullscreen mode
  7451. if (document["fullscreen"] || document["fullScreen"] || document["mozFullScreen"] || document["webkitIsFullScreen"]) {
  7452. if (!GLFW.active.fullscreen) {
  7453. resizeNeeded = width != screen.width || height != screen.height;
  7454. GLFW.active.storedX = GLFW.active.x;
  7455. GLFW.active.storedY = GLFW.active.y;
  7456. GLFW.active.storedWidth = GLFW.active.width;
  7457. GLFW.active.storedHeight = GLFW.active.height;
  7458. GLFW.active.x = GLFW.active.y = 0;
  7459. GLFW.active.width = screen.width;
  7460. GLFW.active.height = screen.height;
  7461. GLFW.active.fullscreen = true;
  7462. }
  7463. // If the client is reverting from fullscreen mode
  7464. } else if (GLFW.active.fullscreen == true) {
  7465. resizeNeeded = width != GLFW.active.storedWidth || height != GLFW.active.storedHeight;
  7466. GLFW.active.x = GLFW.active.storedX;
  7467. GLFW.active.y = GLFW.active.storedY;
  7468. GLFW.active.width = GLFW.active.storedWidth;
  7469. GLFW.active.height = GLFW.active.storedHeight;
  7470. GLFW.active.fullscreen = false;
  7471. }
  7472. if (resizeNeeded) {
  7473. // width or height is changed (fullscreen / exit fullscreen) which will call this listener back
  7474. // with proper framebufferWidth/framebufferHeight
  7475. Browser.setCanvasSize(GLFW.active.width, GLFW.active.height);
  7476. } else if (GLFW.active.width != width ||
  7477. GLFW.active.height != height ||
  7478. GLFW.active.framebufferWidth != framebufferWidth ||
  7479. GLFW.active.framebufferHeight != framebufferHeight) {
  7480. GLFW.active.width = width;
  7481. GLFW.active.height = height;
  7482. GLFW.active.framebufferWidth = framebufferWidth;
  7483. GLFW.active.framebufferHeight = framebufferHeight;
  7484. GLFW.onWindowSizeChanged();
  7485. GLFW.onFramebufferSizeChanged();
  7486. }
  7487. },
  7488. onWindowSizeChanged:() => {
  7489. if (!GLFW.active) return;
  7490. if (GLFW.active.windowSizeFunc) {
  7491. getWasmTableEntry(GLFW.active.windowSizeFunc)(GLFW.active.id, GLFW.active.width, GLFW.active.height);
  7492. }
  7493. },
  7494. onFramebufferSizeChanged:() => {
  7495. if (!GLFW.active) return;
  7496. if (GLFW.active.framebufferSizeFunc) {
  7497. getWasmTableEntry(GLFW.active.framebufferSizeFunc)(GLFW.active.id, GLFW.active.framebufferWidth, GLFW.active.framebufferHeight);
  7498. }
  7499. },
  7500. onWindowContentScaleChanged:(scale) => {
  7501. GLFW.scale = scale;
  7502. if (!GLFW.active) return;
  7503. if (GLFW.active.windowContentScaleFunc) {
  7504. getWasmTableEntry(GLFW.active.windowContentScaleFunc)(GLFW.active.id, GLFW.scale, GLFW.scale);
  7505. }
  7506. },
  7507. getTime:() => _emscripten_get_now() / 1000,
  7508. setWindowTitle:(winid, title) => {
  7509. var win = GLFW.WindowFromId(winid);
  7510. if (!win) return;
  7511. win.title = title;
  7512. if (GLFW.active.id == win.id) {
  7513. _emscripten_set_window_title(title);
  7514. }
  7515. },
  7516. setJoystickCallback:(cbfun) => {
  7517. var prevcbfun = GLFW.joystickFunc;
  7518. GLFW.joystickFunc = cbfun;
  7519. GLFW.refreshJoysticks();
  7520. return prevcbfun;
  7521. },
  7522. joys:{
  7523. },
  7524. lastGamepadState:[],
  7525. lastGamepadStateFrame:null,
  7526. refreshJoysticks:() => {
  7527. // Produce a new Gamepad API sample if we are ticking a new game frame, or if not using emscripten_set_main_loop() at all to drive animation.
  7528. if (MainLoop.currentFrameNumber !== GLFW.lastGamepadStateFrame || !MainLoop.currentFrameNumber) {
  7529. GLFW.lastGamepadState = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads || []);
  7530. GLFW.lastGamepadStateFrame = MainLoop.currentFrameNumber;
  7531. for (var joy = 0; joy < GLFW.lastGamepadState.length; ++joy) {
  7532. var gamepad = GLFW.lastGamepadState[joy];
  7533. if (gamepad) {
  7534. if (!GLFW.joys[joy]) {
  7535. out('glfw joystick connected:',joy);
  7536. GLFW.joys[joy] = {
  7537. id: stringToNewUTF8(gamepad.id),
  7538. buttonsCount: gamepad.buttons.length,
  7539. axesCount: gamepad.axes.length,
  7540. buttons: _malloc(gamepad.buttons.length),
  7541. axes: _malloc(gamepad.axes.length*4),
  7542. };
  7543. if (GLFW.joystickFunc) {
  7544. getWasmTableEntry(GLFW.joystickFunc)(joy, 0x00040001); // GLFW_CONNECTED
  7545. }
  7546. }
  7547. var data = GLFW.joys[joy];
  7548. for (var i = 0; i < gamepad.buttons.length; ++i) {
  7549. HEAP8[data.buttons + i] = gamepad.buttons[i].pressed;
  7550. }
  7551. for (var i = 0; i < gamepad.axes.length; ++i) {
  7552. HEAPF32[((data.axes + i*4)>>2)] = gamepad.axes[i];
  7553. }
  7554. } else {
  7555. if (GLFW.joys[joy]) {
  7556. out('glfw joystick disconnected',joy);
  7557. if (GLFW.joystickFunc) {
  7558. getWasmTableEntry(GLFW.joystickFunc)(joy, 0x00040002); // GLFW_DISCONNECTED
  7559. }
  7560. _free(GLFW.joys[joy].id);
  7561. _free(GLFW.joys[joy].buttons);
  7562. _free(GLFW.joys[joy].axes);
  7563. delete GLFW.joys[joy];
  7564. }
  7565. }
  7566. }
  7567. }
  7568. },
  7569. setKeyCallback:(winid, cbfun) => {
  7570. var win = GLFW.WindowFromId(winid);
  7571. if (!win) return null;
  7572. var prevcbfun = win.keyFunc;
  7573. win.keyFunc = cbfun;
  7574. return prevcbfun;
  7575. },
  7576. setCharCallback:(winid, cbfun) => {
  7577. var win = GLFW.WindowFromId(winid);
  7578. if (!win) return null;
  7579. var prevcbfun = win.charFunc;
  7580. win.charFunc = cbfun;
  7581. return prevcbfun;
  7582. },
  7583. setMouseButtonCallback:(winid, cbfun) => {
  7584. var win = GLFW.WindowFromId(winid);
  7585. if (!win) return null;
  7586. var prevcbfun = win.mouseButtonFunc;
  7587. win.mouseButtonFunc = cbfun;
  7588. return prevcbfun;
  7589. },
  7590. setCursorPosCallback:(winid, cbfun) => {
  7591. var win = GLFW.WindowFromId(winid);
  7592. if (!win) return null;
  7593. var prevcbfun = win.cursorPosFunc;
  7594. win.cursorPosFunc = cbfun;
  7595. return prevcbfun;
  7596. },
  7597. setScrollCallback:(winid, cbfun) => {
  7598. var win = GLFW.WindowFromId(winid);
  7599. if (!win) return null;
  7600. var prevcbfun = win.scrollFunc;
  7601. win.scrollFunc = cbfun;
  7602. return prevcbfun;
  7603. },
  7604. setDropCallback:(winid, cbfun) => {
  7605. var win = GLFW.WindowFromId(winid);
  7606. if (!win) return null;
  7607. var prevcbfun = win.dropFunc;
  7608. win.dropFunc = cbfun;
  7609. return prevcbfun;
  7610. },
  7611. onDrop:(event) => {
  7612. if (!GLFW.active || !GLFW.active.dropFunc) return;
  7613. if (!event.dataTransfer || !event.dataTransfer.files || event.dataTransfer.files.length == 0) return;
  7614. event.preventDefault();
  7615. var filenames = _malloc(event.dataTransfer.files.length*4);
  7616. var filenamesArray = [];
  7617. var count = event.dataTransfer.files.length;
  7618. // Read and save the files to emscripten's FS
  7619. var written = 0;
  7620. var drop_dir = '.glfw_dropped_files';
  7621. FS.createPath('/', drop_dir);
  7622. function save(file) {
  7623. var path = '/' + drop_dir + '/' + file.name.replace(/\//g, '_');
  7624. var reader = new FileReader();
  7625. reader.onloadend = (e) => {
  7626. if (reader.readyState != 2) { // not DONE
  7627. ++written;
  7628. out('failed to read dropped file: '+file.name+': '+reader.error);
  7629. return;
  7630. }
  7631. var data = e.target.result;
  7632. FS.writeFile(path, new Uint8Array(data));
  7633. if (++written === count) {
  7634. getWasmTableEntry(GLFW.active.dropFunc)(GLFW.active.id, count, filenames);
  7635. for (var i = 0; i < filenamesArray.length; ++i) {
  7636. _free(filenamesArray[i]);
  7637. }
  7638. _free(filenames);
  7639. }
  7640. };
  7641. reader.readAsArrayBuffer(file);
  7642. var filename = stringToNewUTF8(path);
  7643. filenamesArray.push(filename);
  7644. HEAPU32[((filenames + i*4)>>2)] = filename;
  7645. }
  7646. for (var i = 0; i < count; ++i) {
  7647. save(event.dataTransfer.files[i]);
  7648. }
  7649. return false;
  7650. },
  7651. onDragover:(event) => {
  7652. if (!GLFW.active || !GLFW.active.dropFunc) return;
  7653. event.preventDefault();
  7654. return false;
  7655. },
  7656. setWindowSizeCallback:(winid, cbfun) => {
  7657. var win = GLFW.WindowFromId(winid);
  7658. if (!win) return null;
  7659. var prevcbfun = win.windowSizeFunc;
  7660. win.windowSizeFunc = cbfun;
  7661. return prevcbfun;
  7662. },
  7663. setWindowCloseCallback:(winid, cbfun) => {
  7664. var win = GLFW.WindowFromId(winid);
  7665. if (!win) return null;
  7666. var prevcbfun = win.windowCloseFunc;
  7667. win.windowCloseFunc = cbfun;
  7668. return prevcbfun;
  7669. },
  7670. setWindowRefreshCallback:(winid, cbfun) => {
  7671. var win = GLFW.WindowFromId(winid);
  7672. if (!win) return null;
  7673. var prevcbfun = win.windowRefreshFunc;
  7674. win.windowRefreshFunc = cbfun;
  7675. return prevcbfun;
  7676. },
  7677. onClickRequestPointerLock:(e) => {
  7678. var canvas = Browser.getCanvas();
  7679. if (!Browser.pointerLock && canvas.requestPointerLock) {
  7680. canvas.requestPointerLock();
  7681. e.preventDefault();
  7682. }
  7683. },
  7684. setInputMode:(winid, mode, value) => {
  7685. var win = GLFW.WindowFromId(winid);
  7686. if (!win) return;
  7687. switch (mode) {
  7688. case 0x00033001: { // GLFW_CURSOR
  7689. var canvas = Browser.getCanvas();
  7690. switch (value) {
  7691. case 0x00034001: { // GLFW_CURSOR_NORMAL
  7692. win.inputModes[mode] = value;
  7693. canvas.removeEventListener('click', GLFW.onClickRequestPointerLock, true);
  7694. canvas.exitPointerLock();
  7695. break;
  7696. }
  7697. case 0x00034002: { // GLFW_CURSOR_HIDDEN
  7698. err('glfwSetInputMode called with GLFW_CURSOR_HIDDEN value not implemented');
  7699. break;
  7700. }
  7701. case 0x00034003: { // GLFW_CURSOR_DISABLED
  7702. win.inputModes[mode] = value;
  7703. canvas.addEventListener('click', GLFW.onClickRequestPointerLock, true);
  7704. canvas.requestPointerLock();
  7705. break;
  7706. }
  7707. default: {
  7708. err(`glfwSetInputMode called with unknown value parameter value: ${value}`);
  7709. break;
  7710. }
  7711. }
  7712. break;
  7713. }
  7714. case 0x00033002: { // GLFW_STICKY_KEYS
  7715. err('glfwSetInputMode called with GLFW_STICKY_KEYS mode not implemented');
  7716. break;
  7717. }
  7718. case 0x00033003: { // GLFW_STICKY_MOUSE_BUTTONS
  7719. err('glfwSetInputMode called with GLFW_STICKY_MOUSE_BUTTONS mode not implemented');
  7720. break;
  7721. }
  7722. case 0x00033004: { // GLFW_LOCK_KEY_MODS
  7723. err('glfwSetInputMode called with GLFW_LOCK_KEY_MODS mode not implemented');
  7724. break;
  7725. }
  7726. case 0x000330005: { // GLFW_RAW_MOUSE_MOTION
  7727. err('glfwSetInputMode called with GLFW_RAW_MOUSE_MOTION mode not implemented');
  7728. break;
  7729. }
  7730. default: {
  7731. err(`glfwSetInputMode called with unknown mode parameter value: ${mode}`);
  7732. break;
  7733. }
  7734. }
  7735. },
  7736. getKey:(winid, key) => {
  7737. var win = GLFW.WindowFromId(winid);
  7738. if (!win) return 0;
  7739. return win.keys[key];
  7740. },
  7741. getMouseButton:(winid, button) => {
  7742. var win = GLFW.WindowFromId(winid);
  7743. if (!win) return 0;
  7744. return (win.buttons & (1 << button)) > 0;
  7745. },
  7746. getCursorPos:(winid, x, y) => {
  7747. HEAPF64[((x)>>3)] = Browser.mouseX;
  7748. HEAPF64[((y)>>3)] = Browser.mouseY;
  7749. },
  7750. getMousePos:(winid, x, y) => {
  7751. HEAP32[((x)>>2)] = Browser.mouseX;
  7752. HEAP32[((y)>>2)] = Browser.mouseY;
  7753. },
  7754. setCursorPos:(winid, x, y) => {
  7755. },
  7756. getWindowPos:(winid, x, y) => {
  7757. var wx = 0;
  7758. var wy = 0;
  7759. var win = GLFW.WindowFromId(winid);
  7760. if (win) {
  7761. wx = win.x;
  7762. wy = win.y;
  7763. }
  7764. if (x) {
  7765. HEAP32[((x)>>2)] = wx;
  7766. }
  7767. if (y) {
  7768. HEAP32[((y)>>2)] = wy;
  7769. }
  7770. },
  7771. setWindowPos:(winid, x, y) => {
  7772. var win = GLFW.WindowFromId(winid);
  7773. if (!win) return;
  7774. win.x = x;
  7775. win.y = y;
  7776. },
  7777. getWindowSize:(winid, width, height) => {
  7778. var ww = 0;
  7779. var wh = 0;
  7780. var win = GLFW.WindowFromId(winid);
  7781. if (win) {
  7782. ww = win.width;
  7783. wh = win.height;
  7784. }
  7785. if (width) {
  7786. HEAP32[((width)>>2)] = ww;
  7787. }
  7788. if (height) {
  7789. HEAP32[((height)>>2)] = wh;
  7790. }
  7791. },
  7792. setWindowSize:(winid, width, height) => {
  7793. var win = GLFW.WindowFromId(winid);
  7794. if (!win) return;
  7795. if (GLFW.active.id == win.id) {
  7796. Browser.setCanvasSize(width, height); // triggers the listener (onCanvasResize) + windowSizeFunc
  7797. }
  7798. },
  7799. defaultWindowHints:() => {
  7800. GLFW.hints = Object.assign({}, GLFW.defaultHints);
  7801. },
  7802. createWindow:(width, height, title, monitor, share) => {
  7803. var i, id;
  7804. for (i = 0; i < GLFW.windows.length && GLFW.windows[i] !== null; i++) {
  7805. // no-op
  7806. }
  7807. if (i > 0) throw "glfwCreateWindow only supports one window at time currently";
  7808. // id for window
  7809. id = i + 1;
  7810. // not valid
  7811. if (width <= 0 || height <= 0) return 0;
  7812. if (monitor) {
  7813. Browser.requestFullscreen();
  7814. } else {
  7815. Browser.setCanvasSize(width, height);
  7816. }
  7817. // Create context when there are no existing alive windows
  7818. for (i = 0; i < GLFW.windows.length && GLFW.windows[i] == null; i++) {
  7819. // no-op
  7820. }
  7821. const canvas = Browser.getCanvas();
  7822. var useWebGL = GLFW.hints[0x00022001] > 0; // Use WebGL when we are told to based on GLFW_CLIENT_API
  7823. if (i == GLFW.windows.length) {
  7824. if (useWebGL) {
  7825. var contextAttributes = {
  7826. antialias: (GLFW.hints[0x0002100D] > 1), // GLFW_SAMPLES
  7827. depth: (GLFW.hints[0x00021005] > 0), // GLFW_DEPTH_BITS
  7828. stencil: (GLFW.hints[0x00021006] > 0), // GLFW_STENCIL_BITS
  7829. alpha: (GLFW.hints[0x00021004] > 0) // GLFW_ALPHA_BITS
  7830. }
  7831. Browser.createContext(canvas, /*useWebGL=*/true, /*setInModule=*/true, contextAttributes);
  7832. } else {
  7833. Browser.init();
  7834. }
  7835. }
  7836. // If context creation failed, do not return a valid window
  7837. if (!Module['ctx'] && useWebGL) return 0;
  7838. // Initializes the framebuffer size from the canvas
  7839. var win = new GLFW_Window(id, width, height, canvas.width, canvas.height, title, monitor, share);
  7840. // Set window to array
  7841. if (id - 1 == GLFW.windows.length) {
  7842. GLFW.windows.push(win);
  7843. } else {
  7844. GLFW.windows[id - 1] = win;
  7845. }
  7846. GLFW.active = win;
  7847. GLFW.adjustCanvasDimensions();
  7848. return win.id;
  7849. },
  7850. destroyWindow:(winid) => {
  7851. var win = GLFW.WindowFromId(winid);
  7852. if (!win) return;
  7853. if (win.windowCloseFunc) {
  7854. getWasmTableEntry(win.windowCloseFunc)(win.id);
  7855. }
  7856. GLFW.windows[win.id - 1] = null;
  7857. if (GLFW.active.id == win.id)
  7858. GLFW.active = null;
  7859. // Destroy context when no alive windows
  7860. for (var i = 0; i < GLFW.windows.length; i++)
  7861. if (GLFW.windows[i] !== null) return;
  7862. delete Module['ctx'];
  7863. },
  7864. swapBuffers:(winid) => {
  7865. },
  7866. requestFullscreen(lockPointer, resizeCanvas) {
  7867. Browser.lockPointer = lockPointer;
  7868. Browser.resizeCanvas = resizeCanvas;
  7869. if (typeof Browser.lockPointer == 'undefined') Browser.lockPointer = true;
  7870. if (typeof Browser.resizeCanvas == 'undefined') Browser.resizeCanvas = false;
  7871. var canvas = Browser.getCanvas();
  7872. function fullscreenChange() {
  7873. Browser.isFullscreen = false;
  7874. var canvasContainer = canvas.parentNode;
  7875. if ((document['fullscreenElement'] || document['mozFullScreenElement'] ||
  7876. document['msFullscreenElement'] || document['webkitFullscreenElement'] ||
  7877. document['webkitCurrentFullScreenElement']) === canvasContainer) {
  7878. canvas.exitFullscreen = Browser.exitFullscreen;
  7879. if (Browser.lockPointer) canvas.requestPointerLock();
  7880. Browser.isFullscreen = true;
  7881. if (Browser.resizeCanvas) {
  7882. Browser.setFullscreenCanvasSize();
  7883. } else {
  7884. Browser.updateCanvasDimensions(canvas);
  7885. Browser.updateResizeListeners();
  7886. }
  7887. } else {
  7888. // remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen
  7889. canvasContainer.parentNode.insertBefore(canvas, canvasContainer);
  7890. canvasContainer.parentNode.removeChild(canvasContainer);
  7891. if (Browser.resizeCanvas) {
  7892. Browser.setWindowedCanvasSize();
  7893. } else {
  7894. Browser.updateCanvasDimensions(canvas);
  7895. Browser.updateResizeListeners();
  7896. }
  7897. }
  7898. Module['onFullScreen']?.(Browser.isFullscreen);
  7899. Module['onFullscreen']?.(Browser.isFullscreen);
  7900. }
  7901. if (!Browser.fullscreenHandlersInstalled) {
  7902. Browser.fullscreenHandlersInstalled = true;
  7903. document.addEventListener('fullscreenchange', fullscreenChange, false);
  7904. document.addEventListener('mozfullscreenchange', fullscreenChange, false);
  7905. document.addEventListener('webkitfullscreenchange', fullscreenChange, false);
  7906. document.addEventListener('MSFullscreenChange', fullscreenChange, false);
  7907. }
  7908. // 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
  7909. var canvasContainer = document.createElement("div");
  7910. canvas.parentNode.insertBefore(canvasContainer, canvas);
  7911. canvasContainer.appendChild(canvas);
  7912. // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size)
  7913. canvasContainer.requestFullscreen = canvasContainer['requestFullscreen'] ||
  7914. canvasContainer['mozRequestFullScreen'] ||
  7915. canvasContainer['msRequestFullscreen'] ||
  7916. (canvasContainer['webkitRequestFullscreen'] ? () => canvasContainer['webkitRequestFullscreen'](Element['ALLOW_KEYBOARD_INPUT']) : null) ||
  7917. (canvasContainer['webkitRequestFullScreen'] ? () => canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) : null);
  7918. canvasContainer.requestFullscreen();
  7919. },
  7920. updateCanvasDimensions(canvas, wNative, hNative) {
  7921. const scale = GLFW.getHiDPIScale();
  7922. if (wNative && hNative) {
  7923. canvas.widthNative = wNative;
  7924. canvas.heightNative = hNative;
  7925. } else {
  7926. wNative = canvas.widthNative;
  7927. hNative = canvas.heightNative;
  7928. }
  7929. var w = wNative;
  7930. var h = hNative;
  7931. if (Module['forcedAspectRatio'] && Module['forcedAspectRatio'] > 0) {
  7932. if (w/h < Module['forcedAspectRatio']) {
  7933. w = Math.round(h * Module['forcedAspectRatio']);
  7934. } else {
  7935. h = Math.round(w / Module['forcedAspectRatio']);
  7936. }
  7937. }
  7938. if (((document['fullscreenElement'] || document['mozFullScreenElement'] ||
  7939. document['msFullscreenElement'] || document['webkitFullscreenElement'] ||
  7940. document['webkitCurrentFullScreenElement']) === canvas.parentNode) && (typeof screen != 'undefined')) {
  7941. var factor = Math.min(screen.width / w, screen.height / h);
  7942. w = Math.round(w * factor);
  7943. h = Math.round(h * factor);
  7944. }
  7945. if (Browser.resizeCanvas) {
  7946. wNative = w;
  7947. hNative = h;
  7948. }
  7949. const wNativeScaled = Math.floor(wNative * scale);
  7950. const hNativeScaled = Math.floor(hNative * scale);
  7951. if (canvas.width != wNativeScaled) canvas.width = wNativeScaled;
  7952. if (canvas.height != hNativeScaled) canvas.height = hNativeScaled;
  7953. if (typeof canvas.style != 'undefined') {
  7954. if (!GLFW.isCSSScalingEnabled()) {
  7955. canvas.style.setProperty( "width", wNative + "px", "important");
  7956. canvas.style.setProperty("height", hNative + "px", "important");
  7957. } else {
  7958. canvas.style.removeProperty( "width");
  7959. canvas.style.removeProperty("height");
  7960. }
  7961. }
  7962. },
  7963. calculateMouseCoords(pageX, pageY) {
  7964. // Calculate the movement based on the changes
  7965. // in the coordinates.
  7966. const rect = Browser.getCanvas().getBoundingClientRect();
  7967. // Neither .scrollX or .pageXOffset are defined in a spec, but
  7968. // we prefer .scrollX because it is currently in a spec draft.
  7969. // (see: http://www.w3.org/TR/2013/WD-cssom-view-20131217/)
  7970. var scrollX = ((typeof window.scrollX != 'undefined') ? window.scrollX : window.pageXOffset);
  7971. var scrollY = ((typeof window.scrollY != 'undefined') ? window.scrollY : window.pageYOffset);
  7972. // If this assert lands, it's likely because the browser doesn't support scrollX or pageXOffset
  7973. // and we have no viable fallback.
  7974. assert((typeof scrollX != 'undefined') && (typeof scrollY != 'undefined'), 'Unable to retrieve scroll position, mouse positions likely broken.');
  7975. var adjustedX = pageX - (scrollX + rect.left);
  7976. var adjustedY = pageY - (scrollY + rect.top);
  7977. // getBoundingClientRect() returns dimension affected by CSS, so as a result:
  7978. // - when CSS scaling is enabled, this will fix the mouse coordinates to match the width/height of the window
  7979. // - otherwise the CSS width/height are forced to the width/height of the GLFW window (see updateCanvasDimensions),
  7980. // so there is no need to adjust the position
  7981. if (GLFW.isCSSScalingEnabled() && GLFW.active) {
  7982. adjustedX = adjustedX * (GLFW.active.width / rect.width);
  7983. adjustedY = adjustedY * (GLFW.active.height / rect.height);
  7984. }
  7985. return { x: adjustedX, y: adjustedY };
  7986. },
  7987. setWindowAttrib:(winid, attrib, value) => {
  7988. var win = GLFW.WindowFromId(winid);
  7989. if (!win) return;
  7990. const isHiDPIAware = GLFW.isHiDPIAware();
  7991. win.attributes[attrib] = value;
  7992. if (isHiDPIAware !== GLFW.isHiDPIAware())
  7993. GLFW.adjustCanvasDimensions();
  7994. },
  7995. getDevicePixelRatio() {
  7996. return (typeof devicePixelRatio == 'number' && devicePixelRatio) || 1.0;
  7997. },
  7998. isHiDPIAware() {
  7999. if (GLFW.active)
  8000. return GLFW.active.attributes[0x0002200C] > 0; // GLFW_SCALE_TO_MONITOR
  8001. else
  8002. return false;
  8003. },
  8004. isCSSScalingEnabled() {
  8005. return !GLFW.isHiDPIAware();
  8006. },
  8007. adjustCanvasDimensions() {
  8008. if (GLFW.active) {
  8009. Browser.updateCanvasDimensions(Browser.getCanvas(), GLFW.active.width, GLFW.active.height);
  8010. Browser.updateResizeListeners();
  8011. }
  8012. },
  8013. getHiDPIScale() {
  8014. return GLFW.isHiDPIAware() ? GLFW.scale : 1.0;
  8015. },
  8016. onDevicePixelRatioChange() {
  8017. GLFW.onWindowContentScaleChanged(GLFW.getDevicePixelRatio());
  8018. GLFW.adjustCanvasDimensions();
  8019. },
  8020. GLFW2ParamToGLFW3Param:(param) => {
  8021. var table = {
  8022. 0x00030001:0, // GLFW_MOUSE_CURSOR
  8023. 0x00030002:0, // GLFW_STICKY_KEYS
  8024. 0x00030003:0, // GLFW_STICKY_MOUSE_BUTTONS
  8025. 0x00030004:0, // GLFW_SYSTEM_KEYS
  8026. 0x00030005:0, // GLFW_KEY_REPEAT
  8027. 0x00030006:0, // GLFW_AUTO_POLL_EVENTS
  8028. 0x00020001:0, // GLFW_OPENED
  8029. 0x00020002:0, // GLFW_ACTIVE
  8030. 0x00020003:0, // GLFW_ICONIFIED
  8031. 0x00020004:0, // GLFW_ACCELERATED
  8032. 0x00020005:0x00021001, // GLFW_RED_BITS
  8033. 0x00020006:0x00021002, // GLFW_GREEN_BITS
  8034. 0x00020007:0x00021003, // GLFW_BLUE_BITS
  8035. 0x00020008:0x00021004, // GLFW_ALPHA_BITS
  8036. 0x00020009:0x00021005, // GLFW_DEPTH_BITS
  8037. 0x0002000A:0x00021006, // GLFW_STENCIL_BITS
  8038. 0x0002000B:0x0002100F, // GLFW_REFRESH_RATE
  8039. 0x0002000C:0x00021007, // GLFW_ACCUM_RED_BITS
  8040. 0x0002000D:0x00021008, // GLFW_ACCUM_GREEN_BITS
  8041. 0x0002000E:0x00021009, // GLFW_ACCUM_BLUE_BITS
  8042. 0x0002000F:0x0002100A, // GLFW_ACCUM_ALPHA_BITS
  8043. 0x00020010:0x0002100B, // GLFW_AUX_BUFFERS
  8044. 0x00020011:0x0002100C, // GLFW_STEREO
  8045. 0x00020012:0, // GLFW_WINDOW_NO_RESIZE
  8046. 0x00020013:0x0002100D, // GLFW_FSAA_SAMPLES
  8047. 0x00020014:0x00022002, // GLFW_OPENGL_VERSION_MAJOR
  8048. 0x00020015:0x00022003, // GLFW_OPENGL_VERSION_MINOR
  8049. 0x00020016:0x00022006, // GLFW_OPENGL_FORWARD_COMPAT
  8050. 0x00020017:0x00022007, // GLFW_OPENGL_DEBUG_CONTEXT
  8051. 0x00020018:0x00022008, // GLFW_OPENGL_PROFILE
  8052. };
  8053. return table[param];
  8054. },
  8055. };
  8056. var _glfwCreateWindow = (width, height, title, monitor, share) => GLFW.createWindow(width, height, title, monitor, share);
  8057. var _glfwDefaultWindowHints = () => GLFW.defaultWindowHints();
  8058. var _glfwDestroyWindow = (winid) => GLFW.destroyWindow(winid);
  8059. var _glfwGetPrimaryMonitor = () => 1;
  8060. var _glfwGetTime = () => GLFW.getTime() - GLFW.initialTime;
  8061. var _glfwGetVideoModes = (monitor, count) => {
  8062. HEAP32[((count)>>2)] = 0;
  8063. return 0;
  8064. };
  8065. var _glfwInit = () => {
  8066. if (GLFW.windows) return 1; // GL_TRUE
  8067. GLFW.initialTime = GLFW.getTime();
  8068. GLFW.defaultWindowHints();
  8069. GLFW.windows = new Array()
  8070. GLFW.active = null;
  8071. GLFW.scale = GLFW.getDevicePixelRatio();
  8072. window.addEventListener('gamepadconnected', GLFW.onGamepadConnected, true);
  8073. window.addEventListener('gamepaddisconnected', GLFW.onGamepadDisconnected, true);
  8074. window.addEventListener('keydown', GLFW.onKeydown, true);
  8075. window.addEventListener('keypress', GLFW.onKeyPress, true);
  8076. window.addEventListener('keyup', GLFW.onKeyup, true);
  8077. window.addEventListener('blur', GLFW.onBlur, true);
  8078. // watch for devicePixelRatio changes
  8079. GLFW.devicePixelRatioMQL = window.matchMedia('(resolution: ' + GLFW.getDevicePixelRatio() + 'dppx)');
  8080. GLFW.devicePixelRatioMQL.addEventListener('change', GLFW.onDevicePixelRatioChange);
  8081. var canvas = Browser.getCanvas();
  8082. canvas.addEventListener('touchmove', GLFW.onMousemove, true);
  8083. canvas.addEventListener('touchstart', GLFW.onMouseButtonDown, true);
  8084. canvas.addEventListener('touchcancel', GLFW.onMouseButtonUp, true);
  8085. canvas.addEventListener('touchend', GLFW.onMouseButtonUp, true);
  8086. canvas.addEventListener('mousemove', GLFW.onMousemove, true);
  8087. canvas.addEventListener('mousedown', GLFW.onMouseButtonDown, true);
  8088. canvas.addEventListener("mouseup", GLFW.onMouseButtonUp, true);
  8089. canvas.addEventListener('wheel', GLFW.onMouseWheel, true);
  8090. canvas.addEventListener('mousewheel', GLFW.onMouseWheel, true);
  8091. canvas.addEventListener('mouseenter', GLFW.onMouseenter, true);
  8092. canvas.addEventListener('mouseleave', GLFW.onMouseleave, true);
  8093. canvas.addEventListener('drop', GLFW.onDrop, true);
  8094. canvas.addEventListener('dragover', GLFW.onDragover, true);
  8095. // Overriding implementation to account for HiDPI
  8096. Browser.requestFullscreen = GLFW.requestFullscreen;
  8097. Browser.calculateMouseCoords = GLFW.calculateMouseCoords;
  8098. Browser.updateCanvasDimensions = GLFW.updateCanvasDimensions;
  8099. Browser.resizeListeners.push((width, height) => {
  8100. if (GLFW.isHiDPIAware()) {
  8101. var canvas = Browser.getCanvas();
  8102. GLFW.onCanvasResize(canvas.clientWidth, canvas.clientHeight, width, height);
  8103. } else {
  8104. GLFW.onCanvasResize(width, height, width, height);
  8105. }
  8106. });
  8107. return 1; // GL_TRUE
  8108. };
  8109. var _glfwMakeContextCurrent = (winid) => 0;
  8110. var _glfwSetCharCallback = (winid, cbfun) => GLFW.setCharCallback(winid, cbfun);
  8111. var _glfwSetCursorEnterCallback = (winid, cbfun) => {
  8112. var win = GLFW.WindowFromId(winid);
  8113. if (!win) return null;
  8114. var prevcbfun = win.cursorEnterFunc;
  8115. win.cursorEnterFunc = cbfun;
  8116. return prevcbfun;
  8117. };
  8118. var _glfwSetCursorPosCallback = (winid, cbfun) => GLFW.setCursorPosCallback(winid, cbfun);
  8119. var _glfwSetDropCallback = (winid, cbfun) => GLFW.setDropCallback(winid, cbfun);
  8120. var _glfwSetErrorCallback = (cbfun) => {
  8121. var prevcbfun = GLFW.errorFunc;
  8122. GLFW.errorFunc = cbfun;
  8123. return prevcbfun;
  8124. };
  8125. var _glfwSetKeyCallback = (winid, cbfun) => GLFW.setKeyCallback(winid, cbfun);
  8126. var _glfwSetMouseButtonCallback = (winid, cbfun) => GLFW.setMouseButtonCallback(winid, cbfun);
  8127. var _glfwSetScrollCallback = (winid, cbfun) => GLFW.setScrollCallback(winid, cbfun);
  8128. var _glfwSetWindowContentScaleCallback = (winid, cbfun) => {
  8129. var win = GLFW.WindowFromId(winid);
  8130. if (!win) return null;
  8131. var prevcbfun = win.windowContentScaleFunc;
  8132. win.windowContentScaleFunc = cbfun;
  8133. return prevcbfun;
  8134. };
  8135. var _glfwSetWindowFocusCallback = (winid, cbfun) => {
  8136. var win = GLFW.WindowFromId(winid);
  8137. if (!win) return null;
  8138. var prevcbfun = win.windowFocusFunc;
  8139. win.windowFocusFunc = cbfun;
  8140. return prevcbfun;
  8141. };
  8142. var _glfwSetWindowIconifyCallback = (winid, cbfun) => {
  8143. var win = GLFW.WindowFromId(winid);
  8144. if (!win) return null;
  8145. var prevcbfun = win.windowIconifyFunc;
  8146. win.windowIconifyFunc = cbfun;
  8147. return prevcbfun;
  8148. };
  8149. var _glfwSetWindowShouldClose = (winid, value) => {
  8150. var win = GLFW.WindowFromId(winid);
  8151. if (!win) return;
  8152. win.shouldClose = value;
  8153. };
  8154. var _glfwSetWindowSizeCallback = (winid, cbfun) => GLFW.setWindowSizeCallback(winid, cbfun);
  8155. var _glfwSwapBuffers = (winid) => GLFW.swapBuffers(winid);
  8156. var _glfwTerminate = () => {
  8157. window.removeEventListener('gamepadconnected', GLFW.onGamepadConnected, true);
  8158. window.removeEventListener('gamepaddisconnected', GLFW.onGamepadDisconnected, true);
  8159. window.removeEventListener('keydown', GLFW.onKeydown, true);
  8160. window.removeEventListener('keypress', GLFW.onKeyPress, true);
  8161. window.removeEventListener('keyup', GLFW.onKeyup, true);
  8162. window.removeEventListener('blur', GLFW.onBlur, true);
  8163. var canvas = Browser.getCanvas();
  8164. canvas.removeEventListener('touchmove', GLFW.onMousemove, true);
  8165. canvas.removeEventListener('touchstart', GLFW.onMouseButtonDown, true);
  8166. canvas.removeEventListener('touchcancel', GLFW.onMouseButtonUp, true);
  8167. canvas.removeEventListener('touchend', GLFW.onMouseButtonUp, true);
  8168. canvas.removeEventListener('mousemove', GLFW.onMousemove, true);
  8169. canvas.removeEventListener('mousedown', GLFW.onMouseButtonDown, true);
  8170. canvas.removeEventListener('mouseup', GLFW.onMouseButtonUp, true);
  8171. canvas.removeEventListener('wheel', GLFW.onMouseWheel, true);
  8172. canvas.removeEventListener('mousewheel', GLFW.onMouseWheel, true);
  8173. canvas.removeEventListener('mouseenter', GLFW.onMouseenter, true);
  8174. canvas.removeEventListener('mouseleave', GLFW.onMouseleave, true);
  8175. canvas.removeEventListener('drop', GLFW.onDrop, true);
  8176. canvas.removeEventListener('dragover', GLFW.onDragover, true);
  8177. if (GLFW.devicePixelRatioMQL)
  8178. GLFW.devicePixelRatioMQL.removeEventListener('change', GLFW.onDevicePixelRatioChange);
  8179. canvas.width = canvas.height = 1;
  8180. GLFW.windows = null;
  8181. GLFW.active = null;
  8182. };
  8183. var _glfwWindowHint = (target, hint) => {
  8184. GLFW.hints[target] = hint;
  8185. };
  8186. FS.createPreloadedFile = FS_createPreloadedFile;
  8187. FS.staticInit();
  8188. // Set module methods based on EXPORTED_RUNTIME_METHODS
  8189. ;
  8190. for (var i = 0; i < 32; ++i) tempFixedLengthArray.push(new Array(i));;
  8191. var miniTempWebGLFloatBuffersStorage = new Float32Array(288);
  8192. // Create GL_POOL_TEMP_BUFFERS_SIZE+1 temporary buffers, for uploads of size 0 through GL_POOL_TEMP_BUFFERS_SIZE inclusive
  8193. for (/**@suppress{duplicate}*/var i = 0; i <= 288; ++i) {
  8194. miniTempWebGLFloatBuffers[i] = miniTempWebGLFloatBuffersStorage.subarray(0, i);
  8195. };
  8196. var miniTempWebGLIntBuffersStorage = new Int32Array(288);
  8197. // Create GL_POOL_TEMP_BUFFERS_SIZE+1 temporary buffers, for uploads of size 0 through GL_POOL_TEMP_BUFFERS_SIZE inclusive
  8198. for (/**@suppress{duplicate}*/var i = 0; i <= 288; ++i) {
  8199. miniTempWebGLIntBuffers[i] = miniTempWebGLIntBuffersStorage.subarray(0, i);
  8200. };
  8201. Module['requestAnimationFrame'] = MainLoop.requestAnimationFrame;
  8202. Module['pauseMainLoop'] = MainLoop.pause;
  8203. Module['resumeMainLoop'] = MainLoop.resume;
  8204. MainLoop.init();;
  8205. // exports
  8206. Module['requestFullscreen'] = Browser.requestFullscreen;
  8207. Module['requestFullScreen'] = Browser.requestFullScreen;
  8208. Module['setCanvasSize'] = Browser.setCanvasSize;
  8209. Module['getUserMedia'] = Browser.getUserMedia;
  8210. Module['createContext'] = Browser.createContext;
  8211. ;
  8212. function checkIncomingModuleAPI() {
  8213. ignoredModuleProp('fetchSettings');
  8214. }
  8215. var wasmImports = {
  8216. /** @export */
  8217. __assert_fail: ___assert_fail,
  8218. /** @export */
  8219. __syscall_faccessat: ___syscall_faccessat,
  8220. /** @export */
  8221. __syscall_fcntl64: ___syscall_fcntl64,
  8222. /** @export */
  8223. __syscall_getcwd: ___syscall_getcwd,
  8224. /** @export */
  8225. __syscall_ioctl: ___syscall_ioctl,
  8226. /** @export */
  8227. __syscall_openat: ___syscall_openat,
  8228. /** @export */
  8229. _abort_js: __abort_js,
  8230. /** @export */
  8231. _localtime_js: __localtime_js,
  8232. /** @export */
  8233. _tzset_js: __tzset_js,
  8234. /** @export */
  8235. clock_time_get: _clock_time_get,
  8236. /** @export */
  8237. emscripten_asm_const_int: _emscripten_asm_const_int,
  8238. /** @export */
  8239. emscripten_date_now: _emscripten_date_now,
  8240. /** @export */
  8241. emscripten_get_element_css_size: _emscripten_get_element_css_size,
  8242. /** @export */
  8243. emscripten_get_gamepad_status: _emscripten_get_gamepad_status,
  8244. /** @export */
  8245. emscripten_get_now: _emscripten_get_now,
  8246. /** @export */
  8247. emscripten_get_num_gamepads: _emscripten_get_num_gamepads,
  8248. /** @export */
  8249. emscripten_glActiveTexture: _emscripten_glActiveTexture,
  8250. /** @export */
  8251. emscripten_glAttachShader: _emscripten_glAttachShader,
  8252. /** @export */
  8253. emscripten_glBeginQueryEXT: _emscripten_glBeginQueryEXT,
  8254. /** @export */
  8255. emscripten_glBindAttribLocation: _emscripten_glBindAttribLocation,
  8256. /** @export */
  8257. emscripten_glBindBuffer: _emscripten_glBindBuffer,
  8258. /** @export */
  8259. emscripten_glBindFramebuffer: _emscripten_glBindFramebuffer,
  8260. /** @export */
  8261. emscripten_glBindRenderbuffer: _emscripten_glBindRenderbuffer,
  8262. /** @export */
  8263. emscripten_glBindTexture: _emscripten_glBindTexture,
  8264. /** @export */
  8265. emscripten_glBindVertexArrayOES: _emscripten_glBindVertexArrayOES,
  8266. /** @export */
  8267. emscripten_glBlendColor: _emscripten_glBlendColor,
  8268. /** @export */
  8269. emscripten_glBlendEquation: _emscripten_glBlendEquation,
  8270. /** @export */
  8271. emscripten_glBlendEquationSeparate: _emscripten_glBlendEquationSeparate,
  8272. /** @export */
  8273. emscripten_glBlendFunc: _emscripten_glBlendFunc,
  8274. /** @export */
  8275. emscripten_glBlendFuncSeparate: _emscripten_glBlendFuncSeparate,
  8276. /** @export */
  8277. emscripten_glBufferData: _emscripten_glBufferData,
  8278. /** @export */
  8279. emscripten_glBufferSubData: _emscripten_glBufferSubData,
  8280. /** @export */
  8281. emscripten_glCheckFramebufferStatus: _emscripten_glCheckFramebufferStatus,
  8282. /** @export */
  8283. emscripten_glClear: _emscripten_glClear,
  8284. /** @export */
  8285. emscripten_glClearColor: _emscripten_glClearColor,
  8286. /** @export */
  8287. emscripten_glClearDepthf: _emscripten_glClearDepthf,
  8288. /** @export */
  8289. emscripten_glClearStencil: _emscripten_glClearStencil,
  8290. /** @export */
  8291. emscripten_glClipControlEXT: _emscripten_glClipControlEXT,
  8292. /** @export */
  8293. emscripten_glColorMask: _emscripten_glColorMask,
  8294. /** @export */
  8295. emscripten_glCompileShader: _emscripten_glCompileShader,
  8296. /** @export */
  8297. emscripten_glCompressedTexImage2D: _emscripten_glCompressedTexImage2D,
  8298. /** @export */
  8299. emscripten_glCompressedTexSubImage2D: _emscripten_glCompressedTexSubImage2D,
  8300. /** @export */
  8301. emscripten_glCopyTexImage2D: _emscripten_glCopyTexImage2D,
  8302. /** @export */
  8303. emscripten_glCopyTexSubImage2D: _emscripten_glCopyTexSubImage2D,
  8304. /** @export */
  8305. emscripten_glCreateProgram: _emscripten_glCreateProgram,
  8306. /** @export */
  8307. emscripten_glCreateShader: _emscripten_glCreateShader,
  8308. /** @export */
  8309. emscripten_glCullFace: _emscripten_glCullFace,
  8310. /** @export */
  8311. emscripten_glDeleteBuffers: _emscripten_glDeleteBuffers,
  8312. /** @export */
  8313. emscripten_glDeleteFramebuffers: _emscripten_glDeleteFramebuffers,
  8314. /** @export */
  8315. emscripten_glDeleteProgram: _emscripten_glDeleteProgram,
  8316. /** @export */
  8317. emscripten_glDeleteQueriesEXT: _emscripten_glDeleteQueriesEXT,
  8318. /** @export */
  8319. emscripten_glDeleteRenderbuffers: _emscripten_glDeleteRenderbuffers,
  8320. /** @export */
  8321. emscripten_glDeleteShader: _emscripten_glDeleteShader,
  8322. /** @export */
  8323. emscripten_glDeleteTextures: _emscripten_glDeleteTextures,
  8324. /** @export */
  8325. emscripten_glDeleteVertexArraysOES: _emscripten_glDeleteVertexArraysOES,
  8326. /** @export */
  8327. emscripten_glDepthFunc: _emscripten_glDepthFunc,
  8328. /** @export */
  8329. emscripten_glDepthMask: _emscripten_glDepthMask,
  8330. /** @export */
  8331. emscripten_glDepthRangef: _emscripten_glDepthRangef,
  8332. /** @export */
  8333. emscripten_glDetachShader: _emscripten_glDetachShader,
  8334. /** @export */
  8335. emscripten_glDisable: _emscripten_glDisable,
  8336. /** @export */
  8337. emscripten_glDisableVertexAttribArray: _emscripten_glDisableVertexAttribArray,
  8338. /** @export */
  8339. emscripten_glDrawArrays: _emscripten_glDrawArrays,
  8340. /** @export */
  8341. emscripten_glDrawArraysInstancedANGLE: _emscripten_glDrawArraysInstancedANGLE,
  8342. /** @export */
  8343. emscripten_glDrawBuffersWEBGL: _emscripten_glDrawBuffersWEBGL,
  8344. /** @export */
  8345. emscripten_glDrawElements: _emscripten_glDrawElements,
  8346. /** @export */
  8347. emscripten_glDrawElementsInstancedANGLE: _emscripten_glDrawElementsInstancedANGLE,
  8348. /** @export */
  8349. emscripten_glEnable: _emscripten_glEnable,
  8350. /** @export */
  8351. emscripten_glEnableVertexAttribArray: _emscripten_glEnableVertexAttribArray,
  8352. /** @export */
  8353. emscripten_glEndQueryEXT: _emscripten_glEndQueryEXT,
  8354. /** @export */
  8355. emscripten_glFinish: _emscripten_glFinish,
  8356. /** @export */
  8357. emscripten_glFlush: _emscripten_glFlush,
  8358. /** @export */
  8359. emscripten_glFramebufferRenderbuffer: _emscripten_glFramebufferRenderbuffer,
  8360. /** @export */
  8361. emscripten_glFramebufferTexture2D: _emscripten_glFramebufferTexture2D,
  8362. /** @export */
  8363. emscripten_glFrontFace: _emscripten_glFrontFace,
  8364. /** @export */
  8365. emscripten_glGenBuffers: _emscripten_glGenBuffers,
  8366. /** @export */
  8367. emscripten_glGenFramebuffers: _emscripten_glGenFramebuffers,
  8368. /** @export */
  8369. emscripten_glGenQueriesEXT: _emscripten_glGenQueriesEXT,
  8370. /** @export */
  8371. emscripten_glGenRenderbuffers: _emscripten_glGenRenderbuffers,
  8372. /** @export */
  8373. emscripten_glGenTextures: _emscripten_glGenTextures,
  8374. /** @export */
  8375. emscripten_glGenVertexArraysOES: _emscripten_glGenVertexArraysOES,
  8376. /** @export */
  8377. emscripten_glGenerateMipmap: _emscripten_glGenerateMipmap,
  8378. /** @export */
  8379. emscripten_glGetActiveAttrib: _emscripten_glGetActiveAttrib,
  8380. /** @export */
  8381. emscripten_glGetActiveUniform: _emscripten_glGetActiveUniform,
  8382. /** @export */
  8383. emscripten_glGetAttachedShaders: _emscripten_glGetAttachedShaders,
  8384. /** @export */
  8385. emscripten_glGetAttribLocation: _emscripten_glGetAttribLocation,
  8386. /** @export */
  8387. emscripten_glGetBooleanv: _emscripten_glGetBooleanv,
  8388. /** @export */
  8389. emscripten_glGetBufferParameteriv: _emscripten_glGetBufferParameteriv,
  8390. /** @export */
  8391. emscripten_glGetError: _emscripten_glGetError,
  8392. /** @export */
  8393. emscripten_glGetFloatv: _emscripten_glGetFloatv,
  8394. /** @export */
  8395. emscripten_glGetFramebufferAttachmentParameteriv: _emscripten_glGetFramebufferAttachmentParameteriv,
  8396. /** @export */
  8397. emscripten_glGetIntegerv: _emscripten_glGetIntegerv,
  8398. /** @export */
  8399. emscripten_glGetProgramInfoLog: _emscripten_glGetProgramInfoLog,
  8400. /** @export */
  8401. emscripten_glGetProgramiv: _emscripten_glGetProgramiv,
  8402. /** @export */
  8403. emscripten_glGetQueryObjecti64vEXT: _emscripten_glGetQueryObjecti64vEXT,
  8404. /** @export */
  8405. emscripten_glGetQueryObjectivEXT: _emscripten_glGetQueryObjectivEXT,
  8406. /** @export */
  8407. emscripten_glGetQueryObjectui64vEXT: _emscripten_glGetQueryObjectui64vEXT,
  8408. /** @export */
  8409. emscripten_glGetQueryObjectuivEXT: _emscripten_glGetQueryObjectuivEXT,
  8410. /** @export */
  8411. emscripten_glGetQueryivEXT: _emscripten_glGetQueryivEXT,
  8412. /** @export */
  8413. emscripten_glGetRenderbufferParameteriv: _emscripten_glGetRenderbufferParameteriv,
  8414. /** @export */
  8415. emscripten_glGetShaderInfoLog: _emscripten_glGetShaderInfoLog,
  8416. /** @export */
  8417. emscripten_glGetShaderPrecisionFormat: _emscripten_glGetShaderPrecisionFormat,
  8418. /** @export */
  8419. emscripten_glGetShaderSource: _emscripten_glGetShaderSource,
  8420. /** @export */
  8421. emscripten_glGetShaderiv: _emscripten_glGetShaderiv,
  8422. /** @export */
  8423. emscripten_glGetString: _emscripten_glGetString,
  8424. /** @export */
  8425. emscripten_glGetTexParameterfv: _emscripten_glGetTexParameterfv,
  8426. /** @export */
  8427. emscripten_glGetTexParameteriv: _emscripten_glGetTexParameteriv,
  8428. /** @export */
  8429. emscripten_glGetUniformLocation: _emscripten_glGetUniformLocation,
  8430. /** @export */
  8431. emscripten_glGetUniformfv: _emscripten_glGetUniformfv,
  8432. /** @export */
  8433. emscripten_glGetUniformiv: _emscripten_glGetUniformiv,
  8434. /** @export */
  8435. emscripten_glGetVertexAttribPointerv: _emscripten_glGetVertexAttribPointerv,
  8436. /** @export */
  8437. emscripten_glGetVertexAttribfv: _emscripten_glGetVertexAttribfv,
  8438. /** @export */
  8439. emscripten_glGetVertexAttribiv: _emscripten_glGetVertexAttribiv,
  8440. /** @export */
  8441. emscripten_glHint: _emscripten_glHint,
  8442. /** @export */
  8443. emscripten_glIsBuffer: _emscripten_glIsBuffer,
  8444. /** @export */
  8445. emscripten_glIsEnabled: _emscripten_glIsEnabled,
  8446. /** @export */
  8447. emscripten_glIsFramebuffer: _emscripten_glIsFramebuffer,
  8448. /** @export */
  8449. emscripten_glIsProgram: _emscripten_glIsProgram,
  8450. /** @export */
  8451. emscripten_glIsQueryEXT: _emscripten_glIsQueryEXT,
  8452. /** @export */
  8453. emscripten_glIsRenderbuffer: _emscripten_glIsRenderbuffer,
  8454. /** @export */
  8455. emscripten_glIsShader: _emscripten_glIsShader,
  8456. /** @export */
  8457. emscripten_glIsTexture: _emscripten_glIsTexture,
  8458. /** @export */
  8459. emscripten_glIsVertexArrayOES: _emscripten_glIsVertexArrayOES,
  8460. /** @export */
  8461. emscripten_glLineWidth: _emscripten_glLineWidth,
  8462. /** @export */
  8463. emscripten_glLinkProgram: _emscripten_glLinkProgram,
  8464. /** @export */
  8465. emscripten_glPixelStorei: _emscripten_glPixelStorei,
  8466. /** @export */
  8467. emscripten_glPolygonModeWEBGL: _emscripten_glPolygonModeWEBGL,
  8468. /** @export */
  8469. emscripten_glPolygonOffset: _emscripten_glPolygonOffset,
  8470. /** @export */
  8471. emscripten_glPolygonOffsetClampEXT: _emscripten_glPolygonOffsetClampEXT,
  8472. /** @export */
  8473. emscripten_glQueryCounterEXT: _emscripten_glQueryCounterEXT,
  8474. /** @export */
  8475. emscripten_glReadPixels: _emscripten_glReadPixels,
  8476. /** @export */
  8477. emscripten_glReleaseShaderCompiler: _emscripten_glReleaseShaderCompiler,
  8478. /** @export */
  8479. emscripten_glRenderbufferStorage: _emscripten_glRenderbufferStorage,
  8480. /** @export */
  8481. emscripten_glSampleCoverage: _emscripten_glSampleCoverage,
  8482. /** @export */
  8483. emscripten_glScissor: _emscripten_glScissor,
  8484. /** @export */
  8485. emscripten_glShaderBinary: _emscripten_glShaderBinary,
  8486. /** @export */
  8487. emscripten_glShaderSource: _emscripten_glShaderSource,
  8488. /** @export */
  8489. emscripten_glStencilFunc: _emscripten_glStencilFunc,
  8490. /** @export */
  8491. emscripten_glStencilFuncSeparate: _emscripten_glStencilFuncSeparate,
  8492. /** @export */
  8493. emscripten_glStencilMask: _emscripten_glStencilMask,
  8494. /** @export */
  8495. emscripten_glStencilMaskSeparate: _emscripten_glStencilMaskSeparate,
  8496. /** @export */
  8497. emscripten_glStencilOp: _emscripten_glStencilOp,
  8498. /** @export */
  8499. emscripten_glStencilOpSeparate: _emscripten_glStencilOpSeparate,
  8500. /** @export */
  8501. emscripten_glTexImage2D: _emscripten_glTexImage2D,
  8502. /** @export */
  8503. emscripten_glTexParameterf: _emscripten_glTexParameterf,
  8504. /** @export */
  8505. emscripten_glTexParameterfv: _emscripten_glTexParameterfv,
  8506. /** @export */
  8507. emscripten_glTexParameteri: _emscripten_glTexParameteri,
  8508. /** @export */
  8509. emscripten_glTexParameteriv: _emscripten_glTexParameteriv,
  8510. /** @export */
  8511. emscripten_glTexSubImage2D: _emscripten_glTexSubImage2D,
  8512. /** @export */
  8513. emscripten_glUniform1f: _emscripten_glUniform1f,
  8514. /** @export */
  8515. emscripten_glUniform1fv: _emscripten_glUniform1fv,
  8516. /** @export */
  8517. emscripten_glUniform1i: _emscripten_glUniform1i,
  8518. /** @export */
  8519. emscripten_glUniform1iv: _emscripten_glUniform1iv,
  8520. /** @export */
  8521. emscripten_glUniform2f: _emscripten_glUniform2f,
  8522. /** @export */
  8523. emscripten_glUniform2fv: _emscripten_glUniform2fv,
  8524. /** @export */
  8525. emscripten_glUniform2i: _emscripten_glUniform2i,
  8526. /** @export */
  8527. emscripten_glUniform2iv: _emscripten_glUniform2iv,
  8528. /** @export */
  8529. emscripten_glUniform3f: _emscripten_glUniform3f,
  8530. /** @export */
  8531. emscripten_glUniform3fv: _emscripten_glUniform3fv,
  8532. /** @export */
  8533. emscripten_glUniform3i: _emscripten_glUniform3i,
  8534. /** @export */
  8535. emscripten_glUniform3iv: _emscripten_glUniform3iv,
  8536. /** @export */
  8537. emscripten_glUniform4f: _emscripten_glUniform4f,
  8538. /** @export */
  8539. emscripten_glUniform4fv: _emscripten_glUniform4fv,
  8540. /** @export */
  8541. emscripten_glUniform4i: _emscripten_glUniform4i,
  8542. /** @export */
  8543. emscripten_glUniform4iv: _emscripten_glUniform4iv,
  8544. /** @export */
  8545. emscripten_glUniformMatrix2fv: _emscripten_glUniformMatrix2fv,
  8546. /** @export */
  8547. emscripten_glUniformMatrix3fv: _emscripten_glUniformMatrix3fv,
  8548. /** @export */
  8549. emscripten_glUniformMatrix4fv: _emscripten_glUniformMatrix4fv,
  8550. /** @export */
  8551. emscripten_glUseProgram: _emscripten_glUseProgram,
  8552. /** @export */
  8553. emscripten_glValidateProgram: _emscripten_glValidateProgram,
  8554. /** @export */
  8555. emscripten_glVertexAttrib1f: _emscripten_glVertexAttrib1f,
  8556. /** @export */
  8557. emscripten_glVertexAttrib1fv: _emscripten_glVertexAttrib1fv,
  8558. /** @export */
  8559. emscripten_glVertexAttrib2f: _emscripten_glVertexAttrib2f,
  8560. /** @export */
  8561. emscripten_glVertexAttrib2fv: _emscripten_glVertexAttrib2fv,
  8562. /** @export */
  8563. emscripten_glVertexAttrib3f: _emscripten_glVertexAttrib3f,
  8564. /** @export */
  8565. emscripten_glVertexAttrib3fv: _emscripten_glVertexAttrib3fv,
  8566. /** @export */
  8567. emscripten_glVertexAttrib4f: _emscripten_glVertexAttrib4f,
  8568. /** @export */
  8569. emscripten_glVertexAttrib4fv: _emscripten_glVertexAttrib4fv,
  8570. /** @export */
  8571. emscripten_glVertexAttribDivisorANGLE: _emscripten_glVertexAttribDivisorANGLE,
  8572. /** @export */
  8573. emscripten_glVertexAttribPointer: _emscripten_glVertexAttribPointer,
  8574. /** @export */
  8575. emscripten_glViewport: _emscripten_glViewport,
  8576. /** @export */
  8577. emscripten_resize_heap: _emscripten_resize_heap,
  8578. /** @export */
  8579. emscripten_sample_gamepad_data: _emscripten_sample_gamepad_data,
  8580. /** @export */
  8581. emscripten_set_canvas_element_size: _emscripten_set_canvas_element_size,
  8582. /** @export */
  8583. emscripten_set_click_callback_on_thread: _emscripten_set_click_callback_on_thread,
  8584. /** @export */
  8585. emscripten_set_fullscreenchange_callback_on_thread: _emscripten_set_fullscreenchange_callback_on_thread,
  8586. /** @export */
  8587. emscripten_set_gamepadconnected_callback_on_thread: _emscripten_set_gamepadconnected_callback_on_thread,
  8588. /** @export */
  8589. emscripten_set_gamepaddisconnected_callback_on_thread: _emscripten_set_gamepaddisconnected_callback_on_thread,
  8590. /** @export */
  8591. emscripten_set_main_loop: _emscripten_set_main_loop,
  8592. /** @export */
  8593. emscripten_set_mousemove_callback_on_thread: _emscripten_set_mousemove_callback_on_thread,
  8594. /** @export */
  8595. emscripten_set_pointerlockchange_callback_on_thread: _emscripten_set_pointerlockchange_callback_on_thread,
  8596. /** @export */
  8597. emscripten_set_resize_callback_on_thread: _emscripten_set_resize_callback_on_thread,
  8598. /** @export */
  8599. emscripten_set_touchcancel_callback_on_thread: _emscripten_set_touchcancel_callback_on_thread,
  8600. /** @export */
  8601. emscripten_set_touchend_callback_on_thread: _emscripten_set_touchend_callback_on_thread,
  8602. /** @export */
  8603. emscripten_set_touchmove_callback_on_thread: _emscripten_set_touchmove_callback_on_thread,
  8604. /** @export */
  8605. emscripten_set_touchstart_callback_on_thread: _emscripten_set_touchstart_callback_on_thread,
  8606. /** @export */
  8607. emscripten_set_window_title: _emscripten_set_window_title,
  8608. /** @export */
  8609. exit: _exit,
  8610. /** @export */
  8611. fd_close: _fd_close,
  8612. /** @export */
  8613. fd_read: _fd_read,
  8614. /** @export */
  8615. fd_seek: _fd_seek,
  8616. /** @export */
  8617. fd_write: _fd_write,
  8618. /** @export */
  8619. glActiveTexture: _glActiveTexture,
  8620. /** @export */
  8621. glAttachShader: _glAttachShader,
  8622. /** @export */
  8623. glBindAttribLocation: _glBindAttribLocation,
  8624. /** @export */
  8625. glBindBuffer: _glBindBuffer,
  8626. /** @export */
  8627. glBindTexture: _glBindTexture,
  8628. /** @export */
  8629. glBlendFunc: _glBlendFunc,
  8630. /** @export */
  8631. glBufferData: _glBufferData,
  8632. /** @export */
  8633. glBufferSubData: _glBufferSubData,
  8634. /** @export */
  8635. glClear: _glClear,
  8636. /** @export */
  8637. glClearColor: _glClearColor,
  8638. /** @export */
  8639. glClearDepthf: _glClearDepthf,
  8640. /** @export */
  8641. glCompileShader: _glCompileShader,
  8642. /** @export */
  8643. glCompressedTexImage2D: _glCompressedTexImage2D,
  8644. /** @export */
  8645. glCreateProgram: _glCreateProgram,
  8646. /** @export */
  8647. glCreateShader: _glCreateShader,
  8648. /** @export */
  8649. glCullFace: _glCullFace,
  8650. /** @export */
  8651. glDeleteBuffers: _glDeleteBuffers,
  8652. /** @export */
  8653. glDeleteProgram: _glDeleteProgram,
  8654. /** @export */
  8655. glDeleteShader: _glDeleteShader,
  8656. /** @export */
  8657. glDeleteTextures: _glDeleteTextures,
  8658. /** @export */
  8659. glDepthFunc: _glDepthFunc,
  8660. /** @export */
  8661. glDetachShader: _glDetachShader,
  8662. /** @export */
  8663. glDisable: _glDisable,
  8664. /** @export */
  8665. glDisableVertexAttribArray: _glDisableVertexAttribArray,
  8666. /** @export */
  8667. glDrawArrays: _glDrawArrays,
  8668. /** @export */
  8669. glDrawElements: _glDrawElements,
  8670. /** @export */
  8671. glEnable: _glEnable,
  8672. /** @export */
  8673. glEnableVertexAttribArray: _glEnableVertexAttribArray,
  8674. /** @export */
  8675. glFrontFace: _glFrontFace,
  8676. /** @export */
  8677. glGenBuffers: _glGenBuffers,
  8678. /** @export */
  8679. glGenTextures: _glGenTextures,
  8680. /** @export */
  8681. glGetAttribLocation: _glGetAttribLocation,
  8682. /** @export */
  8683. glGetFloatv: _glGetFloatv,
  8684. /** @export */
  8685. glGetProgramInfoLog: _glGetProgramInfoLog,
  8686. /** @export */
  8687. glGetProgramiv: _glGetProgramiv,
  8688. /** @export */
  8689. glGetShaderInfoLog: _glGetShaderInfoLog,
  8690. /** @export */
  8691. glGetShaderiv: _glGetShaderiv,
  8692. /** @export */
  8693. glGetString: _glGetString,
  8694. /** @export */
  8695. glGetUniformLocation: _glGetUniformLocation,
  8696. /** @export */
  8697. glLinkProgram: _glLinkProgram,
  8698. /** @export */
  8699. glPixelStorei: _glPixelStorei,
  8700. /** @export */
  8701. glReadPixels: _glReadPixels,
  8702. /** @export */
  8703. glScissor: _glScissor,
  8704. /** @export */
  8705. glShaderSource: _glShaderSource,
  8706. /** @export */
  8707. glTexImage2D: _glTexImage2D,
  8708. /** @export */
  8709. glTexParameteri: _glTexParameteri,
  8710. /** @export */
  8711. glUniform1i: _glUniform1i,
  8712. /** @export */
  8713. glUniform4f: _glUniform4f,
  8714. /** @export */
  8715. glUniformMatrix4fv: _glUniformMatrix4fv,
  8716. /** @export */
  8717. glUseProgram: _glUseProgram,
  8718. /** @export */
  8719. glVertexAttribPointer: _glVertexAttribPointer,
  8720. /** @export */
  8721. glViewport: _glViewport,
  8722. /** @export */
  8723. glfwCreateWindow: _glfwCreateWindow,
  8724. /** @export */
  8725. glfwDefaultWindowHints: _glfwDefaultWindowHints,
  8726. /** @export */
  8727. glfwDestroyWindow: _glfwDestroyWindow,
  8728. /** @export */
  8729. glfwGetPrimaryMonitor: _glfwGetPrimaryMonitor,
  8730. /** @export */
  8731. glfwGetTime: _glfwGetTime,
  8732. /** @export */
  8733. glfwGetVideoModes: _glfwGetVideoModes,
  8734. /** @export */
  8735. glfwInit: _glfwInit,
  8736. /** @export */
  8737. glfwMakeContextCurrent: _glfwMakeContextCurrent,
  8738. /** @export */
  8739. glfwSetCharCallback: _glfwSetCharCallback,
  8740. /** @export */
  8741. glfwSetCursorEnterCallback: _glfwSetCursorEnterCallback,
  8742. /** @export */
  8743. glfwSetCursorPosCallback: _glfwSetCursorPosCallback,
  8744. /** @export */
  8745. glfwSetDropCallback: _glfwSetDropCallback,
  8746. /** @export */
  8747. glfwSetErrorCallback: _glfwSetErrorCallback,
  8748. /** @export */
  8749. glfwSetKeyCallback: _glfwSetKeyCallback,
  8750. /** @export */
  8751. glfwSetMouseButtonCallback: _glfwSetMouseButtonCallback,
  8752. /** @export */
  8753. glfwSetScrollCallback: _glfwSetScrollCallback,
  8754. /** @export */
  8755. glfwSetWindowContentScaleCallback: _glfwSetWindowContentScaleCallback,
  8756. /** @export */
  8757. glfwSetWindowFocusCallback: _glfwSetWindowFocusCallback,
  8758. /** @export */
  8759. glfwSetWindowIconifyCallback: _glfwSetWindowIconifyCallback,
  8760. /** @export */
  8761. glfwSetWindowShouldClose: _glfwSetWindowShouldClose,
  8762. /** @export */
  8763. glfwSetWindowSizeCallback: _glfwSetWindowSizeCallback,
  8764. /** @export */
  8765. glfwSwapBuffers: _glfwSwapBuffers,
  8766. /** @export */
  8767. glfwTerminate: _glfwTerminate,
  8768. /** @export */
  8769. glfwWindowHint: _glfwWindowHint
  8770. };
  8771. var wasmExports;
  8772. createWasm();
  8773. var ___wasm_call_ctors = createExportWrapper('__wasm_call_ctors', 0);
  8774. var _main = Module['_main'] = createExportWrapper('main', 2);
  8775. var _malloc = createExportWrapper('malloc', 1);
  8776. var _free = createExportWrapper('free', 1);
  8777. var _fflush = createExportWrapper('fflush', 1);
  8778. var _strerror = createExportWrapper('strerror', 1);
  8779. var _emscripten_stack_init = () => (_emscripten_stack_init = wasmExports['emscripten_stack_init'])();
  8780. var _emscripten_stack_get_free = () => (_emscripten_stack_get_free = wasmExports['emscripten_stack_get_free'])();
  8781. var _emscripten_stack_get_base = () => (_emscripten_stack_get_base = wasmExports['emscripten_stack_get_base'])();
  8782. var _emscripten_stack_get_end = () => (_emscripten_stack_get_end = wasmExports['emscripten_stack_get_end'])();
  8783. var __emscripten_stack_restore = (a0) => (__emscripten_stack_restore = wasmExports['_emscripten_stack_restore'])(a0);
  8784. var __emscripten_stack_alloc = (a0) => (__emscripten_stack_alloc = wasmExports['_emscripten_stack_alloc'])(a0);
  8785. var _emscripten_stack_get_current = () => (_emscripten_stack_get_current = wasmExports['emscripten_stack_get_current'])();
  8786. // include: postamble.js
  8787. // === Auto-generated postamble setup entry stuff ===
  8788. var missingLibrarySymbols = [
  8789. 'writeI53ToI64Clamped',
  8790. 'writeI53ToI64Signaling',
  8791. 'writeI53ToU64Clamped',
  8792. 'writeI53ToU64Signaling',
  8793. 'convertI32PairToI53',
  8794. 'convertI32PairToI53Checked',
  8795. 'convertU32PairToI53',
  8796. 'stackAlloc',
  8797. 'getTempRet0',
  8798. 'setTempRet0',
  8799. 'growMemory',
  8800. 'inetPton4',
  8801. 'inetNtop4',
  8802. 'inetPton6',
  8803. 'inetNtop6',
  8804. 'readSockaddr',
  8805. 'writeSockaddr',
  8806. 'emscriptenLog',
  8807. 'runMainThreadEmAsm',
  8808. 'getExecutableName',
  8809. 'listenOnce',
  8810. 'autoResumeAudioContext',
  8811. 'getDynCaller',
  8812. 'dynCall',
  8813. 'runtimeKeepalivePush',
  8814. 'runtimeKeepalivePop',
  8815. 'asmjsMangle',
  8816. 'HandleAllocator',
  8817. 'getNativeTypeSize',
  8818. 'addOnInit',
  8819. 'addOnPostCtor',
  8820. 'addOnPreMain',
  8821. 'STACK_SIZE',
  8822. 'STACK_ALIGN',
  8823. 'POINTER_SIZE',
  8824. 'ASSERTIONS',
  8825. 'getCFunc',
  8826. 'ccall',
  8827. 'cwrap',
  8828. 'uleb128Encode',
  8829. 'sigToWasmTypes',
  8830. 'generateFuncType',
  8831. 'convertJsFunctionToWasm',
  8832. 'getEmptyTableSlot',
  8833. 'updateTableMap',
  8834. 'getFunctionAddress',
  8835. 'addFunction',
  8836. 'removeFunction',
  8837. 'reallyNegative',
  8838. 'unSign',
  8839. 'strLen',
  8840. 'reSign',
  8841. 'formatString',
  8842. 'intArrayToString',
  8843. 'AsciiToString',
  8844. 'stringToAscii',
  8845. 'UTF16ToString',
  8846. 'stringToUTF16',
  8847. 'lengthBytesUTF16',
  8848. 'UTF32ToString',
  8849. 'stringToUTF32',
  8850. 'lengthBytesUTF32',
  8851. 'stringToUTF8OnStack',
  8852. 'writeArrayToMemory',
  8853. 'registerKeyEventCallback',
  8854. 'registerWheelEventCallback',
  8855. 'registerFocusEventCallback',
  8856. 'fillDeviceOrientationEventData',
  8857. 'registerDeviceOrientationEventCallback',
  8858. 'fillDeviceMotionEventData',
  8859. 'registerDeviceMotionEventCallback',
  8860. 'screenOrientation',
  8861. 'fillOrientationChangeEventData',
  8862. 'registerOrientationChangeEventCallback',
  8863. 'JSEvents_requestFullscreen',
  8864. 'JSEvents_resizeCanvasForFullscreen',
  8865. 'registerRestoreOldStyle',
  8866. 'hideEverythingExceptGivenElement',
  8867. 'restoreHiddenElements',
  8868. 'setLetterbox',
  8869. 'softFullscreenResizeWebGLRenderTarget',
  8870. 'doRequestFullscreen',
  8871. 'registerPointerlockErrorEventCallback',
  8872. 'requestPointerLock',
  8873. 'fillVisibilityChangeEventData',
  8874. 'registerVisibilityChangeEventCallback',
  8875. 'registerBeforeUnloadEventCallback',
  8876. 'fillBatteryEventData',
  8877. 'battery',
  8878. 'registerBatteryEventCallback',
  8879. 'setCanvasElementSize',
  8880. 'getCanvasElementSize',
  8881. 'jsStackTrace',
  8882. 'getCallstack',
  8883. 'convertPCtoSourceLocation',
  8884. 'getEnvStrings',
  8885. 'wasiRightsToMuslOFlags',
  8886. 'wasiOFlagsToMuslOFlags',
  8887. 'setImmediateWrapped',
  8888. 'safeRequestAnimationFrame',
  8889. 'clearImmediateWrapped',
  8890. 'registerPostMainLoop',
  8891. 'registerPreMainLoop',
  8892. 'getPromise',
  8893. 'makePromise',
  8894. 'idsToPromises',
  8895. 'makePromiseCallback',
  8896. 'ExceptionInfo',
  8897. 'findMatchingCatch',
  8898. 'Browser_asyncPrepareDataCounter',
  8899. 'arraySum',
  8900. 'addDays',
  8901. 'getSocketFromFD',
  8902. 'getSocketAddress',
  8903. 'FS_unlink',
  8904. 'FS_mkdirTree',
  8905. '_setNetworkCallback',
  8906. 'writeGLArray',
  8907. 'registerWebGlEventCallback',
  8908. 'runAndAbortIfError',
  8909. 'ALLOC_NORMAL',
  8910. 'ALLOC_STACK',
  8911. 'allocate',
  8912. 'writeStringToMemory',
  8913. 'writeAsciiToMemory',
  8914. 'setErrNo',
  8915. 'demangle',
  8916. 'stackTrace',
  8917. ];
  8918. missingLibrarySymbols.forEach(missingLibrarySymbol)
  8919. var unexportedSymbols = [
  8920. 'run',
  8921. 'addRunDependency',
  8922. 'removeRunDependency',
  8923. 'out',
  8924. 'err',
  8925. 'callMain',
  8926. 'abort',
  8927. 'wasmMemory',
  8928. 'wasmExports',
  8929. 'writeStackCookie',
  8930. 'checkStackCookie',
  8931. 'writeI53ToI64',
  8932. 'readI53FromI64',
  8933. 'readI53FromU64',
  8934. 'INT53_MAX',
  8935. 'INT53_MIN',
  8936. 'bigintToI53Checked',
  8937. 'stackSave',
  8938. 'stackRestore',
  8939. 'ptrToString',
  8940. 'zeroMemory',
  8941. 'exitJS',
  8942. 'getHeapMax',
  8943. 'abortOnCannotGrowMemory',
  8944. 'ENV',
  8945. 'ERRNO_CODES',
  8946. 'strError',
  8947. 'DNS',
  8948. 'Protocols',
  8949. 'Sockets',
  8950. 'timers',
  8951. 'warnOnce',
  8952. 'readEmAsmArgsArray',
  8953. 'readEmAsmArgs',
  8954. 'runEmAsmFunction',
  8955. 'jstoi_q',
  8956. 'jstoi_s',
  8957. 'handleException',
  8958. 'keepRuntimeAlive',
  8959. 'callUserCallback',
  8960. 'maybeExit',
  8961. 'asyncLoad',
  8962. 'alignMemory',
  8963. 'mmapAlloc',
  8964. 'wasmTable',
  8965. 'noExitRuntime',
  8966. 'addOnPreRun',
  8967. 'addOnExit',
  8968. 'addOnPostRun',
  8969. 'freeTableIndexes',
  8970. 'functionsInTableMap',
  8971. 'setValue',
  8972. 'getValue',
  8973. 'PATH',
  8974. 'PATH_FS',
  8975. 'UTF8Decoder',
  8976. 'UTF8ArrayToString',
  8977. 'UTF8ToString',
  8978. 'stringToUTF8Array',
  8979. 'stringToUTF8',
  8980. 'lengthBytesUTF8',
  8981. 'intArrayFromString',
  8982. 'UTF16Decoder',
  8983. 'stringToNewUTF8',
  8984. 'JSEvents',
  8985. 'specialHTMLTargets',
  8986. 'maybeCStringToJsString',
  8987. 'findEventTarget',
  8988. 'findCanvasEventTarget',
  8989. 'getBoundingClientRect',
  8990. 'fillMouseEventData',
  8991. 'registerMouseEventCallback',
  8992. 'registerUiEventCallback',
  8993. 'fillFullscreenChangeEventData',
  8994. 'registerFullscreenChangeEventCallback',
  8995. 'currentFullscreenStrategy',
  8996. 'restoreOldWindowedStyle',
  8997. 'fillPointerlockChangeEventData',
  8998. 'registerPointerlockChangeEventCallback',
  8999. 'registerTouchEventCallback',
  9000. 'fillGamepadEventData',
  9001. 'registerGamepadEventCallback',
  9002. 'UNWIND_CACHE',
  9003. 'ExitStatus',
  9004. 'checkWasiClock',
  9005. 'doReadv',
  9006. 'doWritev',
  9007. 'initRandomFill',
  9008. 'randomFill',
  9009. 'safeSetTimeout',
  9010. 'emSetImmediate',
  9011. 'emClearImmediate_deps',
  9012. 'emClearImmediate',
  9013. 'promiseMap',
  9014. 'uncaughtExceptionCount',
  9015. 'exceptionLast',
  9016. 'exceptionCaught',
  9017. 'Browser',
  9018. 'getPreloadedImageData__data',
  9019. 'wget',
  9020. 'MONTH_DAYS_REGULAR',
  9021. 'MONTH_DAYS_LEAP',
  9022. 'MONTH_DAYS_REGULAR_CUMULATIVE',
  9023. 'MONTH_DAYS_LEAP_CUMULATIVE',
  9024. 'isLeapYear',
  9025. 'ydayFromDate',
  9026. 'SYSCALLS',
  9027. 'preloadPlugins',
  9028. 'FS_createPreloadedFile',
  9029. 'FS_modeStringToFlags',
  9030. 'FS_getMode',
  9031. 'FS_stdin_getChar_buffer',
  9032. 'FS_stdin_getChar',
  9033. 'FS_createPath',
  9034. 'FS_createDevice',
  9035. 'FS_readFile',
  9036. 'FS',
  9037. 'FS_createDataFile',
  9038. 'FS_createLazyFile',
  9039. 'MEMFS',
  9040. 'TTY',
  9041. 'PIPEFS',
  9042. 'SOCKFS',
  9043. 'tempFixedLengthArray',
  9044. 'miniTempWebGLFloatBuffers',
  9045. 'miniTempWebGLIntBuffers',
  9046. 'heapObjectForWebGLType',
  9047. 'toTypedArrayIndex',
  9048. 'webgl_enable_ANGLE_instanced_arrays',
  9049. 'webgl_enable_OES_vertex_array_object',
  9050. 'webgl_enable_WEBGL_draw_buffers',
  9051. 'webgl_enable_WEBGL_multi_draw',
  9052. 'webgl_enable_EXT_polygon_offset_clamp',
  9053. 'webgl_enable_EXT_clip_control',
  9054. 'webgl_enable_WEBGL_polygon_mode',
  9055. 'GL',
  9056. 'emscriptenWebGLGet',
  9057. 'computeUnpackAlignedImageSize',
  9058. 'colorChannelsInGlTextureFormat',
  9059. 'emscriptenWebGLGetTexPixelData',
  9060. 'emscriptenWebGLGetUniform',
  9061. 'webglGetUniformLocation',
  9062. 'webglPrepareUniformLocationsBeforeFirstUse',
  9063. 'webglGetLeftBracePos',
  9064. 'emscriptenWebGLGetVertexAttrib',
  9065. '__glGetActiveAttribOrUniform',
  9066. 'AL',
  9067. 'GLUT',
  9068. 'EGL',
  9069. 'GLEW',
  9070. 'IDBStore',
  9071. 'SDL',
  9072. 'SDL_gfx',
  9073. 'GLFW_Window',
  9074. 'GLFW',
  9075. 'allocateUTF8',
  9076. 'allocateUTF8OnStack',
  9077. 'print',
  9078. 'printErr',
  9079. ];
  9080. unexportedSymbols.forEach(unexportedRuntimeSymbol);
  9081. var calledRun;
  9082. function callMain() {
  9083. assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on Module["onRuntimeInitialized"])');
  9084. assert(typeof onPreRuns === 'undefined' || onPreRuns.length == 0, 'cannot call main when preRun functions remain to be called');
  9085. var entryFunction = _main;
  9086. var argc = 0;
  9087. var argv = 0;
  9088. try {
  9089. var ret = entryFunction(argc, argv);
  9090. // if we're not running an evented main loop, it's time to exit
  9091. exitJS(ret, /* implicit = */ true);
  9092. return ret;
  9093. } catch (e) {
  9094. return handleException(e);
  9095. }
  9096. }
  9097. function stackCheckInit() {
  9098. // This is normally called automatically during __wasm_call_ctors but need to
  9099. // get these values before even running any of the ctors so we call it redundantly
  9100. // here.
  9101. _emscripten_stack_init();
  9102. // TODO(sbc): Move writeStackCookie to native to to avoid this.
  9103. writeStackCookie();
  9104. }
  9105. function run() {
  9106. if (runDependencies > 0) {
  9107. dependenciesFulfilled = run;
  9108. return;
  9109. }
  9110. stackCheckInit();
  9111. preRun();
  9112. // a preRun added a dependency, run will be called later
  9113. if (runDependencies > 0) {
  9114. dependenciesFulfilled = run;
  9115. return;
  9116. }
  9117. function doRun() {
  9118. // run may have just been called through dependencies being fulfilled just in this very frame,
  9119. // or while the async setStatus time below was happening
  9120. assert(!calledRun);
  9121. calledRun = true;
  9122. Module['calledRun'] = true;
  9123. if (ABORT) return;
  9124. initRuntime();
  9125. preMain();
  9126. Module['onRuntimeInitialized']?.();
  9127. var noInitialRun = Module['noInitialRun'];legacyModuleProp('noInitialRun', 'noInitialRun');
  9128. if (!noInitialRun) callMain();
  9129. postRun();
  9130. }
  9131. if (Module['setStatus']) {
  9132. Module['setStatus']('Running...');
  9133. setTimeout(() => {
  9134. setTimeout(() => Module['setStatus'](''), 1);
  9135. doRun();
  9136. }, 1);
  9137. } else
  9138. {
  9139. doRun();
  9140. }
  9141. checkStackCookie();
  9142. }
  9143. function checkUnflushedContent() {
  9144. // Compiler settings do not allow exiting the runtime, so flushing
  9145. // the streams is not possible. but in ASSERTIONS mode we check
  9146. // if there was something to flush, and if so tell the user they
  9147. // should request that the runtime be exitable.
  9148. // Normally we would not even include flush() at all, but in ASSERTIONS
  9149. // builds we do so just for this check, and here we see if there is any
  9150. // content to flush, that is, we check if there would have been
  9151. // something a non-ASSERTIONS build would have not seen.
  9152. // How we flush the streams depends on whether we are in SYSCALLS_REQUIRE_FILESYSTEM=0
  9153. // mode (which has its own special function for this; otherwise, all
  9154. // the code is inside libc)
  9155. var oldOut = out;
  9156. var oldErr = err;
  9157. var has = false;
  9158. out = err = (x) => {
  9159. has = true;
  9160. }
  9161. try { // it doesn't matter if it fails
  9162. _fflush(0);
  9163. // also flush in the JS FS layer
  9164. ['stdout', 'stderr'].forEach((name) => {
  9165. var info = FS.analyzePath('/dev/' + name);
  9166. if (!info) return;
  9167. var stream = info.object;
  9168. var rdev = stream.rdev;
  9169. var tty = TTY.ttys[rdev];
  9170. if (tty?.output?.length) {
  9171. has = true;
  9172. }
  9173. });
  9174. } catch(e) {}
  9175. out = oldOut;
  9176. err = oldErr;
  9177. if (has) {
  9178. warnOnce('stdio streams had content in them that was not flushed. you should set EXIT_RUNTIME to 1 (see the Emscripten FAQ), or make sure to emit a newline when you printf etc.');
  9179. }
  9180. }
  9181. if (Module['preInit']) {
  9182. if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];
  9183. while (Module['preInit'].length > 0) {
  9184. Module['preInit'].pop()();
  9185. }
  9186. }
  9187. run();
  9188. // end include: postamble.js