tngp.js 382 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424
  1. // The Module object: Our interface to the outside world. We import
  2. // and export values on it. There are various ways Module can be used:
  3. // 1. Not defined. We create it here
  4. // 2. A function parameter, function(Module) { ..generated code.. }
  5. // 3. pre-run appended it, var Module = {}; ..generated code..
  6. // 4. External script tag defines var Module.
  7. // We need to check if Module already exists (e.g. case 3 above).
  8. // Substitution will be replaced with actual code on later stage of the build,
  9. // this way Closure Compiler will not mangle it (e.g. case 4. above).
  10. // Note that if you want to run closure, and also to use Module
  11. // after the generated code, you will need to define var Module = {};
  12. // before the code. Then that object will be used in the code, and you
  13. // can continue to use Module afterwards as well.
  14. var Module = typeof Module != 'undefined' ? Module : {};
  15. // See https://caniuse.com/mdn-javascript_builtins_object_assign
  16. // See https://caniuse.com/mdn-javascript_builtins_bigint64array
  17. // --pre-jses are emitted after the Module integration code, so that they can
  18. // refer to Module (if they choose; they can also define Module)
  19. // {{PRE_JSES}}
  20. // Sometimes an existing Module object exists with properties
  21. // meant to overwrite the default module functionality. Here
  22. // we collect those properties and reapply _after_ we configure
  23. // the current environment's defaults to avoid having to be so
  24. // defensive during initialization.
  25. var moduleOverrides = Object.assign({}, Module);
  26. var arguments_ = [];
  27. var thisProgram = './this.program';
  28. var quit_ = (status, toThrow) => {
  29. throw toThrow;
  30. };
  31. // Determine the runtime environment we are in. You can customize this by
  32. // setting the ENVIRONMENT setting at compile time (see settings.js).
  33. // Attempt to auto-detect the environment
  34. var ENVIRONMENT_IS_WEB = typeof window == 'object';
  35. var ENVIRONMENT_IS_WORKER = typeof importScripts == 'function';
  36. // N.b. Electron.js environment is simultaneously a NODE-environment, but
  37. // also a web environment.
  38. var ENVIRONMENT_IS_NODE = typeof process == 'object' && typeof process.versions == 'object' && typeof process.versions.node == 'string';
  39. var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
  40. if (Module['ENVIRONMENT']) {
  41. 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)');
  42. }
  43. // `/` should be present at the end if `scriptDirectory` is not empty
  44. var scriptDirectory = '';
  45. function locateFile(path) {
  46. if (Module['locateFile']) {
  47. return Module['locateFile'](path, scriptDirectory);
  48. }
  49. return scriptDirectory + path;
  50. }
  51. // Hooks that are implemented differently in different runtime environments.
  52. var read_,
  53. readAsync,
  54. readBinary,
  55. setWindowTitle;
  56. // Normally we don't log exceptions but instead let them bubble out the top
  57. // level where the embedding environment (e.g. the browser) can handle
  58. // them.
  59. // However under v8 and node we sometimes exit the process direcly in which case
  60. // its up to use us to log the exception before exiting.
  61. // If we fix https://github.com/emscripten-core/emscripten/issues/15080
  62. // this may no longer be needed under node.
  63. function logExceptionOnExit(e) {
  64. if (e instanceof ExitStatus) return;
  65. let toLog = e;
  66. if (e && typeof e == 'object' && e.stack) {
  67. toLog = [e, e.stack];
  68. }
  69. err('exiting due to exception: ' + toLog);
  70. }
  71. if (ENVIRONMENT_IS_NODE) {
  72. 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?)');
  73. if (ENVIRONMENT_IS_WORKER) {
  74. scriptDirectory = require('path').dirname(scriptDirectory) + '/';
  75. } else {
  76. scriptDirectory = __dirname + '/';
  77. }
  78. // include: node_shell_read.js
  79. // These modules will usually be used on Node.js. Load them eagerly to avoid
  80. // the complexity of lazy-loading. However, for now we must guard on require()
  81. // actually existing: if the JS is put in a .mjs file (ES6 module) and run on
  82. // node, then we'll detect node as the environment and get here, but require()
  83. // does not exist (since ES6 modules should use |import|). If the code actually
  84. // uses the node filesystem then it will crash, of course, but in the case of
  85. // code that never uses it we don't want to crash here, so the guarding if lets
  86. // such code work properly. See discussion in
  87. // https://github.com/emscripten-core/emscripten/pull/17851
  88. var fs, nodePath;
  89. if (typeof require === 'function') {
  90. fs = require('fs');
  91. nodePath = require('path');
  92. }
  93. read_ = (filename, binary) => {
  94. filename = nodePath['normalize'](filename);
  95. return fs.readFileSync(filename, binary ? undefined : 'utf8');
  96. };
  97. readBinary = (filename) => {
  98. var ret = read_(filename, true);
  99. if (!ret.buffer) {
  100. ret = new Uint8Array(ret);
  101. }
  102. assert(ret.buffer);
  103. return ret;
  104. };
  105. readAsync = (filename, onload, onerror) => {
  106. filename = nodePath['normalize'](filename);
  107. fs.readFile(filename, function(err, data) {
  108. if (err) onerror(err);
  109. else onload(data.buffer);
  110. });
  111. };
  112. // end include: node_shell_read.js
  113. if (process['argv'].length > 1) {
  114. thisProgram = process['argv'][1].replace(/\\/g, '/');
  115. }
  116. arguments_ = process['argv'].slice(2);
  117. if (typeof module != 'undefined') {
  118. module['exports'] = Module;
  119. }
  120. process['on']('uncaughtException', function(ex) {
  121. // suppress ExitStatus exceptions from showing an error
  122. if (!(ex instanceof ExitStatus)) {
  123. throw ex;
  124. }
  125. });
  126. // Without this older versions of node (< v15) will log unhandled rejections
  127. // but return 0, which is not normally the desired behaviour. This is
  128. // not be needed with node v15 and about because it is now the default
  129. // behaviour:
  130. // See https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode
  131. process['on']('unhandledRejection', function(reason) { throw reason; });
  132. quit_ = (status, toThrow) => {
  133. if (keepRuntimeAlive()) {
  134. process['exitCode'] = status;
  135. throw toThrow;
  136. }
  137. logExceptionOnExit(toThrow);
  138. process['exit'](status);
  139. };
  140. Module['inspect'] = function () { return '[Emscripten Module object]'; };
  141. } else
  142. if (ENVIRONMENT_IS_SHELL) {
  143. if ((typeof process == 'object' && typeof require === 'function') || typeof window == 'object' || typeof importScripts == 'function') 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?)');
  144. if (typeof read != 'undefined') {
  145. read_ = function shell_read(f) {
  146. return read(f);
  147. };
  148. }
  149. readBinary = function readBinary(f) {
  150. let data;
  151. if (typeof readbuffer == 'function') {
  152. return new Uint8Array(readbuffer(f));
  153. }
  154. data = read(f, 'binary');
  155. assert(typeof data == 'object');
  156. return data;
  157. };
  158. readAsync = function readAsync(f, onload, onerror) {
  159. setTimeout(() => onload(readBinary(f)), 0);
  160. };
  161. if (typeof scriptArgs != 'undefined') {
  162. arguments_ = scriptArgs;
  163. } else if (typeof arguments != 'undefined') {
  164. arguments_ = arguments;
  165. }
  166. if (typeof quit == 'function') {
  167. quit_ = (status, toThrow) => {
  168. // Unlike node which has process.exitCode, d8 has no such mechanism. So we
  169. // have no way to set the exit code and then let the program exit with
  170. // that code when it naturally stops running (say, when all setTimeouts
  171. // have completed). For that reason we must call `quit` - the only way to
  172. // set the exit code - but quit also halts immediately, so we need to be
  173. // careful of whether the runtime is alive or not, which is why this code
  174. // path looks different than node. It also has the downside that it will
  175. // halt the entire program when no code remains to run, which means this
  176. // is not friendly for bundling this code into a larger codebase, and for
  177. // that reason the "shell" environment is mainly useful for testing whole
  178. // programs by themselves, basically.
  179. if (runtimeKeepaliveCounter) {
  180. throw toThrow;
  181. }
  182. logExceptionOnExit(toThrow);
  183. quit(status);
  184. };
  185. }
  186. if (typeof print != 'undefined') {
  187. // Prefer to use print/printErr where they exist, as they usually work better.
  188. if (typeof console == 'undefined') console = /** @type{!Console} */({});
  189. console.log = /** @type{!function(this:Console, ...*): undefined} */ (print);
  190. console.warn = console.error = /** @type{!function(this:Console, ...*): undefined} */ (typeof printErr != 'undefined' ? printErr : print);
  191. }
  192. } else
  193. // Note that this includes Node.js workers when relevant (pthreads is enabled).
  194. // Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and
  195. // ENVIRONMENT_IS_NODE.
  196. if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
  197. if (ENVIRONMENT_IS_WORKER) { // Check worker, not web, since window could be polyfilled
  198. scriptDirectory = self.location.href;
  199. } else if (typeof document != 'undefined' && document.currentScript) { // web
  200. scriptDirectory = document.currentScript.src;
  201. }
  202. // blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them.
  203. // otherwise, slice off the final part of the url to find the script directory.
  204. // if scriptDirectory does not contain a slash, lastIndexOf will return -1,
  205. // and scriptDirectory will correctly be replaced with an empty string.
  206. // If scriptDirectory contains a query (starting with ?) or a fragment (starting with #),
  207. // they are removed because they could contain a slash.
  208. if (scriptDirectory.indexOf('blob:') !== 0) {
  209. scriptDirectory = scriptDirectory.substr(0, scriptDirectory.replace(/[?#].*/, "").lastIndexOf('/')+1);
  210. } else {
  211. scriptDirectory = '';
  212. }
  213. if (!(typeof window == 'object' || typeof importScripts == 'function')) 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?)');
  214. // Differentiate the Web Worker from the Node Worker case, as reading must
  215. // be done differently.
  216. {
  217. // include: web_or_worker_shell_read.js
  218. read_ = (url) => {
  219. var xhr = new XMLHttpRequest();
  220. xhr.open('GET', url, false);
  221. xhr.send(null);
  222. return xhr.responseText;
  223. }
  224. if (ENVIRONMENT_IS_WORKER) {
  225. readBinary = (url) => {
  226. var xhr = new XMLHttpRequest();
  227. xhr.open('GET', url, false);
  228. xhr.responseType = 'arraybuffer';
  229. xhr.send(null);
  230. return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response));
  231. };
  232. }
  233. readAsync = (url, onload, onerror) => {
  234. var xhr = new XMLHttpRequest();
  235. xhr.open('GET', url, true);
  236. xhr.responseType = 'arraybuffer';
  237. xhr.onload = () => {
  238. if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
  239. onload(xhr.response);
  240. return;
  241. }
  242. onerror();
  243. };
  244. xhr.onerror = onerror;
  245. xhr.send(null);
  246. }
  247. // end include: web_or_worker_shell_read.js
  248. }
  249. setWindowTitle = (title) => document.title = title;
  250. } else
  251. {
  252. throw new Error('environment detection error');
  253. }
  254. var out = Module['print'] || console.log.bind(console);
  255. var err = Module['printErr'] || console.warn.bind(console);
  256. // Merge back in the overrides
  257. Object.assign(Module, moduleOverrides);
  258. // Free the object hierarchy contained in the overrides, this lets the GC
  259. // reclaim data used e.g. in memoryInitializerRequest, which is a large typed array.
  260. moduleOverrides = null;
  261. checkIncomingModuleAPI();
  262. // Emit code to handle expected values on the Module object. This applies Module.x
  263. // to the proper local x. This has two benefits: first, we only emit it if it is
  264. // expected to arrive, and second, by using a local everywhere else that can be
  265. // minified.
  266. if (Module['arguments']) arguments_ = Module['arguments'];legacyModuleProp('arguments', 'arguments_');
  267. if (Module['thisProgram']) thisProgram = Module['thisProgram'];legacyModuleProp('thisProgram', 'thisProgram');
  268. if (Module['quit']) quit_ = Module['quit'];legacyModuleProp('quit', 'quit_');
  269. // perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message
  270. // Assertions on removed incoming Module JS APIs.
  271. assert(typeof Module['memoryInitializerPrefixURL'] == 'undefined', 'Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead');
  272. assert(typeof Module['pthreadMainPrefixURL'] == 'undefined', 'Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead');
  273. assert(typeof Module['cdInitializerPrefixURL'] == 'undefined', 'Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead');
  274. assert(typeof Module['filePackagePrefixURL'] == 'undefined', 'Module.filePackagePrefixURL option was removed, use Module.locateFile instead');
  275. assert(typeof Module['read'] == 'undefined', 'Module.read option was removed (modify read_ in JS)');
  276. assert(typeof Module['readAsync'] == 'undefined', 'Module.readAsync option was removed (modify readAsync in JS)');
  277. assert(typeof Module['readBinary'] == 'undefined', 'Module.readBinary option was removed (modify readBinary in JS)');
  278. assert(typeof Module['setWindowTitle'] == 'undefined', 'Module.setWindowTitle option was removed (modify setWindowTitle in JS)');
  279. assert(typeof Module['TOTAL_MEMORY'] == 'undefined', 'Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY');
  280. legacyModuleProp('read', 'read_');
  281. legacyModuleProp('readAsync', 'readAsync');
  282. legacyModuleProp('readBinary', 'readBinary');
  283. legacyModuleProp('setWindowTitle', 'setWindowTitle');
  284. var IDBFS = 'IDBFS is no longer included by default; build with -lidbfs.js';
  285. var PROXYFS = 'PROXYFS is no longer included by default; build with -lproxyfs.js';
  286. var WORKERFS = 'WORKERFS is no longer included by default; build with -lworkerfs.js';
  287. var NODEFS = 'NODEFS is no longer included by default; build with -lnodefs.js';
  288. assert(!ENVIRONMENT_IS_SHELL, "shell environment detected but not enabled at build time. Add 'shell' to `-sENVIRONMENT` to enable.");
  289. var STACK_ALIGN = 16;
  290. var POINTER_SIZE = 4;
  291. function getNativeTypeSize(type) {
  292. switch (type) {
  293. case 'i1': case 'i8': case 'u8': return 1;
  294. case 'i16': case 'u16': return 2;
  295. case 'i32': case 'u32': return 4;
  296. case 'i64': case 'u64': return 8;
  297. case 'float': return 4;
  298. case 'double': return 8;
  299. default: {
  300. if (type[type.length - 1] === '*') {
  301. return POINTER_SIZE;
  302. }
  303. if (type[0] === 'i') {
  304. const bits = Number(type.substr(1));
  305. assert(bits % 8 === 0, 'getNativeTypeSize invalid bits ' + bits + ', type ' + type);
  306. return bits / 8;
  307. }
  308. return 0;
  309. }
  310. }
  311. }
  312. // include: runtime_debug.js
  313. function legacyModuleProp(prop, newName) {
  314. if (!Object.getOwnPropertyDescriptor(Module, prop)) {
  315. Object.defineProperty(Module, prop, {
  316. configurable: true,
  317. get: function() {
  318. abort('Module.' + prop + ' has been replaced with plain ' + newName + ' (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)');
  319. }
  320. });
  321. }
  322. }
  323. function ignoredModuleProp(prop) {
  324. if (Object.getOwnPropertyDescriptor(Module, prop)) {
  325. abort('`Module.' + prop + '` was supplied but `' + prop + '` not included in INCOMING_MODULE_JS_API');
  326. }
  327. }
  328. // forcing the filesystem exports a few things by default
  329. function isExportedByForceFilesystem(name) {
  330. return name === 'FS_createPath' ||
  331. name === 'FS_createDataFile' ||
  332. name === 'FS_createPreloadedFile' ||
  333. name === 'FS_unlink' ||
  334. name === 'addRunDependency' ||
  335. // The old FS has some functionality that WasmFS lacks.
  336. name === 'FS_createLazyFile' ||
  337. name === 'FS_createDevice' ||
  338. name === 'removeRunDependency';
  339. }
  340. function missingLibrarySymbol(sym) {
  341. if (typeof globalThis !== 'undefined' && !Object.getOwnPropertyDescriptor(globalThis, sym)) {
  342. Object.defineProperty(globalThis, sym, {
  343. configurable: true,
  344. get: function() {
  345. // Can't `abort()` here because it would break code that does runtime
  346. // checks. e.g. `if (typeof SDL === 'undefined')`.
  347. 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';
  348. // DEFAULT_LIBRARY_FUNCS_TO_INCLUDE requires the name as it appears in
  349. // library.js, which means $name for a JS name with no prefix, or name
  350. // for a JS name like _name.
  351. var librarySymbol = sym;
  352. if (!librarySymbol.startsWith('_')) {
  353. librarySymbol = '$' + sym;
  354. }
  355. msg += " (e.g. -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE=" + librarySymbol + ")";
  356. if (isExportedByForceFilesystem(sym)) {
  357. msg += '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you';
  358. }
  359. warnOnce(msg);
  360. return undefined;
  361. }
  362. });
  363. }
  364. }
  365. function unexportedRuntimeSymbol(sym) {
  366. if (!Object.getOwnPropertyDescriptor(Module, sym)) {
  367. Object.defineProperty(Module, sym, {
  368. configurable: true,
  369. get: function() {
  370. var msg = "'" + sym + "' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)";
  371. if (isExportedByForceFilesystem(sym)) {
  372. msg += '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you';
  373. }
  374. abort(msg);
  375. }
  376. });
  377. }
  378. }
  379. // end include: runtime_debug.js
  380. // === Preamble library stuff ===
  381. // Documentation for the public APIs defined in this file must be updated in:
  382. // site/source/docs/api_reference/preamble.js.rst
  383. // A prebuilt local version of the documentation is available at:
  384. // site/build/text/docs/api_reference/preamble.js.txt
  385. // You can also build docs locally as HTML or other formats in site/
  386. // An online HTML version (which may be of a different version of Emscripten)
  387. // is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html
  388. var wasmBinary;
  389. if (Module['wasmBinary']) wasmBinary = Module['wasmBinary'];legacyModuleProp('wasmBinary', 'wasmBinary');
  390. var noExitRuntime = Module['noExitRuntime'] || false;legacyModuleProp('noExitRuntime', 'noExitRuntime');
  391. if (typeof WebAssembly != 'object') {
  392. abort('no native wasm support detected');
  393. }
  394. // Wasm globals
  395. var wasmMemory;
  396. //========================================
  397. // Runtime essentials
  398. //========================================
  399. // whether we are quitting the application. no code should run after this.
  400. // set in exit() and abort()
  401. var ABORT = false;
  402. // set by exit() and abort(). Passed to 'onExit' handler.
  403. // NOTE: This is also used as the process return code code in shell environments
  404. // but only when noExitRuntime is false.
  405. var EXITSTATUS;
  406. /** @type {function(*, string=)} */
  407. function assert(condition, text) {
  408. if (!condition) {
  409. abort('Assertion failed' + (text ? ': ' + text : ''));
  410. }
  411. }
  412. // We used to include malloc/free by default in the past. Show a helpful error in
  413. // builds with assertions.
  414. // include: runtime_strings.js
  415. // runtime_strings.js: String related runtime functions that are part of both
  416. // MINIMAL_RUNTIME and regular runtime.
  417. var UTF8Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder('utf8') : undefined;
  418. /**
  419. * Given a pointer 'idx' to a null-terminated UTF8-encoded string in the given
  420. * array that contains uint8 values, returns a copy of that string as a
  421. * Javascript String object.
  422. * heapOrArray is either a regular array, or a JavaScript typed array view.
  423. * @param {number} idx
  424. * @param {number=} maxBytesToRead
  425. * @return {string}
  426. */
  427. function UTF8ArrayToString(heapOrArray, idx, maxBytesToRead) {
  428. var endIdx = idx + maxBytesToRead;
  429. var endPtr = idx;
  430. // TextDecoder needs to know the byte length in advance, it doesn't stop on
  431. // null terminator by itself. Also, use the length info to avoid running tiny
  432. // strings through TextDecoder, since .subarray() allocates garbage.
  433. // (As a tiny code save trick, compare endPtr against endIdx using a negation,
  434. // so that undefined means Infinity)
  435. while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr;
  436. if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) {
  437. return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr));
  438. }
  439. var str = '';
  440. // If building with TextDecoder, we have already computed the string length
  441. // above, so test loop end condition against that
  442. while (idx < endPtr) {
  443. // For UTF8 byte structure, see:
  444. // http://en.wikipedia.org/wiki/UTF-8#Description
  445. // https://www.ietf.org/rfc/rfc2279.txt
  446. // https://tools.ietf.org/html/rfc3629
  447. var u0 = heapOrArray[idx++];
  448. if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; }
  449. var u1 = heapOrArray[idx++] & 63;
  450. if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; }
  451. var u2 = heapOrArray[idx++] & 63;
  452. if ((u0 & 0xF0) == 0xE0) {
  453. u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
  454. } else {
  455. 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!');
  456. u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heapOrArray[idx++] & 63);
  457. }
  458. if (u0 < 0x10000) {
  459. str += String.fromCharCode(u0);
  460. } else {
  461. var ch = u0 - 0x10000;
  462. str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
  463. }
  464. }
  465. return str;
  466. }
  467. /**
  468. * Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the
  469. * emscripten HEAP, returns a copy of that string as a Javascript String object.
  470. *
  471. * @param {number} ptr
  472. * @param {number=} maxBytesToRead - An optional length that specifies the
  473. * maximum number of bytes to read. You can omit this parameter to scan the
  474. * string until the first \0 byte. If maxBytesToRead is passed, and the string
  475. * at [ptr, ptr+maxBytesToReadr[ contains a null byte in the middle, then the
  476. * string will cut short at that byte index (i.e. maxBytesToRead will not
  477. * produce a string of exact length [ptr, ptr+maxBytesToRead[) N.B. mixing
  478. * frequent uses of UTF8ToString() with and without maxBytesToRead may throw
  479. * JS JIT optimizations off, so it is worth to consider consistently using one
  480. * @return {string}
  481. */
  482. function UTF8ToString(ptr, maxBytesToRead) {
  483. return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : '';
  484. }
  485. /**
  486. * Copies the given Javascript String object 'str' to the given byte array at
  487. * address 'outIdx', encoded in UTF8 form and null-terminated. The copy will
  488. * require at most str.length*4+1 bytes of space in the HEAP. Use the function
  489. * lengthBytesUTF8 to compute the exact number of bytes (excluding null
  490. * terminator) that this function will write.
  491. *
  492. * @param {string} str - The Javascript string to copy.
  493. * @param {ArrayBufferView|Array<number>} heap - The array to copy to. Each
  494. * index in this array is assumed
  495. * to be one 8-byte element.
  496. * @param {number} outIdx - The starting offset in the array to begin the copying.
  497. * @param {number} maxBytesToWrite - The maximum number of bytes this function
  498. * can write to the array. This count should
  499. * include the null terminator, i.e. if
  500. * maxBytesToWrite=1, only the null terminator
  501. * will be written and nothing else.
  502. * maxBytesToWrite=0 does not write any bytes
  503. * to the output, not even the null
  504. * terminator.
  505. * @return {number} The number of bytes written, EXCLUDING the null terminator.
  506. */
  507. function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) {
  508. // Parameter maxBytesToWrite is not optional. Negative values, 0, null,
  509. // undefined and false each don't write out any bytes.
  510. if (!(maxBytesToWrite > 0))
  511. return 0;
  512. var startIdx = outIdx;
  513. var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator.
  514. for (var i = 0; i < str.length; ++i) {
  515. // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code
  516. // unit, not a Unicode code point of the character! So decode
  517. // UTF16->UTF32->UTF8.
  518. // See http://unicode.org/faq/utf_bom.html#utf16-3
  519. // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description
  520. // and https://www.ietf.org/rfc/rfc2279.txt
  521. // and https://tools.ietf.org/html/rfc3629
  522. var u = str.charCodeAt(i); // possibly a lead surrogate
  523. if (u >= 0xD800 && u <= 0xDFFF) {
  524. var u1 = str.charCodeAt(++i);
  525. u = 0x10000 + ((u & 0x3FF) << 10) | (u1 & 0x3FF);
  526. }
  527. if (u <= 0x7F) {
  528. if (outIdx >= endIdx) break;
  529. heap[outIdx++] = u;
  530. } else if (u <= 0x7FF) {
  531. if (outIdx + 1 >= endIdx) break;
  532. heap[outIdx++] = 0xC0 | (u >> 6);
  533. heap[outIdx++] = 0x80 | (u & 63);
  534. } else if (u <= 0xFFFF) {
  535. if (outIdx + 2 >= endIdx) break;
  536. heap[outIdx++] = 0xE0 | (u >> 12);
  537. heap[outIdx++] = 0x80 | ((u >> 6) & 63);
  538. heap[outIdx++] = 0x80 | (u & 63);
  539. } else {
  540. if (outIdx + 3 >= endIdx) break;
  541. 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).');
  542. heap[outIdx++] = 0xF0 | (u >> 18);
  543. heap[outIdx++] = 0x80 | ((u >> 12) & 63);
  544. heap[outIdx++] = 0x80 | ((u >> 6) & 63);
  545. heap[outIdx++] = 0x80 | (u & 63);
  546. }
  547. }
  548. // Null-terminate the pointer to the buffer.
  549. heap[outIdx] = 0;
  550. return outIdx - startIdx;
  551. }
  552. /**
  553. * Copies the given Javascript String object 'str' to the emscripten HEAP at
  554. * address 'outPtr', null-terminated and encoded in UTF8 form. The copy will
  555. * require at most str.length*4+1 bytes of space in the HEAP.
  556. * Use the function lengthBytesUTF8 to compute the exact number of bytes
  557. * (excluding null terminator) that this function will write.
  558. *
  559. * @return {number} The number of bytes written, EXCLUDING the null terminator.
  560. */
  561. function stringToUTF8(str, outPtr, maxBytesToWrite) {
  562. assert(typeof maxBytesToWrite == 'number', 'stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!');
  563. return stringToUTF8Array(str, HEAPU8,outPtr, maxBytesToWrite);
  564. }
  565. /**
  566. * Returns the number of bytes the given Javascript string takes if encoded as a
  567. * UTF8 byte array, EXCLUDING the null terminator byte.
  568. *
  569. * @param {string} str - JavaScript string to operator on
  570. * @return {number} Length, in bytes, of the UTF8 encoded string.
  571. */
  572. function lengthBytesUTF8(str) {
  573. var len = 0;
  574. for (var i = 0; i < str.length; ++i) {
  575. // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code
  576. // unit, not a Unicode code point of the character! So decode
  577. // UTF16->UTF32->UTF8.
  578. // See http://unicode.org/faq/utf_bom.html#utf16-3
  579. var c = str.charCodeAt(i); // possibly a lead surrogate
  580. if (c <= 0x7F) {
  581. len++;
  582. } else if (c <= 0x7FF) {
  583. len += 2;
  584. } else if (c >= 0xD800 && c <= 0xDFFF) {
  585. len += 4; ++i;
  586. } else {
  587. len += 3;
  588. }
  589. }
  590. return len;
  591. }
  592. // end include: runtime_strings.js
  593. // Memory management
  594. var HEAP,
  595. /** @type {!ArrayBuffer} */
  596. buffer,
  597. /** @type {!Int8Array} */
  598. HEAP8,
  599. /** @type {!Uint8Array} */
  600. HEAPU8,
  601. /** @type {!Int16Array} */
  602. HEAP16,
  603. /** @type {!Uint16Array} */
  604. HEAPU16,
  605. /** @type {!Int32Array} */
  606. HEAP32,
  607. /** @type {!Uint32Array} */
  608. HEAPU32,
  609. /** @type {!Float32Array} */
  610. HEAPF32,
  611. /* BigInt64Array type is not correctly defined in closure
  612. /** not-@type {!BigInt64Array} */
  613. HEAP64,
  614. /* BigUInt64Array type is not correctly defined in closure
  615. /** not-t@type {!BigUint64Array} */
  616. HEAPU64,
  617. /** @type {!Float64Array} */
  618. HEAPF64;
  619. function updateGlobalBufferAndViews(buf) {
  620. buffer = buf;
  621. Module['HEAP8'] = HEAP8 = new Int8Array(buf);
  622. Module['HEAP16'] = HEAP16 = new Int16Array(buf);
  623. Module['HEAP32'] = HEAP32 = new Int32Array(buf);
  624. Module['HEAPU8'] = HEAPU8 = new Uint8Array(buf);
  625. Module['HEAPU16'] = HEAPU16 = new Uint16Array(buf);
  626. Module['HEAPU32'] = HEAPU32 = new Uint32Array(buf);
  627. Module['HEAPF32'] = HEAPF32 = new Float32Array(buf);
  628. Module['HEAPF64'] = HEAPF64 = new Float64Array(buf);
  629. Module['HEAP64'] = HEAP64 = new BigInt64Array(buf);
  630. Module['HEAPU64'] = HEAPU64 = new BigUint64Array(buf);
  631. }
  632. var STACK_SIZE = 5242880;
  633. if (Module['STACK_SIZE']) assert(STACK_SIZE === Module['STACK_SIZE'], 'the stack size can no longer be determined at runtime')
  634. var INITIAL_MEMORY = Module['INITIAL_MEMORY'] || 16777216;legacyModuleProp('INITIAL_MEMORY', 'INITIAL_MEMORY');
  635. assert(INITIAL_MEMORY >= STACK_SIZE, 'INITIAL_MEMORY should be larger than STACK_SIZE, was ' + INITIAL_MEMORY + '! (STACK_SIZE=' + STACK_SIZE + ')');
  636. // check for full engine support (use string 'subarray' to avoid closure compiler confusion)
  637. assert(typeof Int32Array != 'undefined' && typeof Float64Array !== 'undefined' && Int32Array.prototype.subarray != undefined && Int32Array.prototype.set != undefined,
  638. 'JS engine does not provide full typed array support');
  639. // If memory is defined in wasm, the user can't provide it.
  640. assert(!Module['wasmMemory'], 'Use of `wasmMemory` detected. Use -sIMPORTED_MEMORY to define wasmMemory externally');
  641. assert(INITIAL_MEMORY == 16777216, 'Detected runtime INITIAL_MEMORY setting. Use -sIMPORTED_MEMORY to define wasmMemory dynamically');
  642. // include: runtime_init_table.js
  643. // In regular non-RELOCATABLE mode the table is exported
  644. // from the wasm module and this will be assigned once
  645. // the exports are available.
  646. var wasmTable;
  647. // end include: runtime_init_table.js
  648. // include: runtime_stack_check.js
  649. // Initializes the stack cookie. Called at the startup of main and at the startup of each thread in pthreads mode.
  650. function writeStackCookie() {
  651. var max = _emscripten_stack_get_end();
  652. assert((max & 3) == 0);
  653. // If the stack ends at address zero we write our cookies 4 bytes into the
  654. // stack. This prevents interference with the (separate) address-zero check
  655. // below.
  656. if (max == 0) {
  657. max += 4;
  658. }
  659. // The stack grow downwards towards _emscripten_stack_get_end.
  660. // We write cookies to the final two words in the stack and detect if they are
  661. // ever overwritten.
  662. HEAPU32[((max)>>2)] = 0x2135467;
  663. HEAPU32[(((max)+(4))>>2)] = 0x89BACDFE;
  664. // Also test the global address 0 for integrity.
  665. HEAPU32[0] = 0x63736d65; /* 'emsc' */
  666. }
  667. function checkStackCookie() {
  668. if (ABORT) return;
  669. var max = _emscripten_stack_get_end();
  670. // See writeStackCookie().
  671. if (max == 0) {
  672. max += 4;
  673. }
  674. var cookie1 = HEAPU32[((max)>>2)];
  675. var cookie2 = HEAPU32[(((max)+(4))>>2)];
  676. if (cookie1 != 0x2135467 || cookie2 != 0x89BACDFE) {
  677. abort('Stack overflow! Stack cookie has been overwritten at ' + ptrToString(max) + ', expected hex dwords 0x89BACDFE and 0x2135467, but received ' + ptrToString(cookie2) + ' ' + ptrToString(cookie1));
  678. }
  679. // Also test the global address 0 for integrity.
  680. if (HEAPU32[0] !== 0x63736d65 /* 'emsc' */) {
  681. abort('Runtime error: The application has corrupted its heap memory area (address zero)!');
  682. }
  683. }
  684. // end include: runtime_stack_check.js
  685. // include: runtime_assertions.js
  686. // Endianness check
  687. (function() {
  688. var h16 = new Int16Array(1);
  689. var h8 = new Int8Array(h16.buffer);
  690. h16[0] = 0x6373;
  691. if (h8[0] !== 0x73 || h8[1] !== 0x63) throw 'Runtime error: expected the system to be little-endian! (Run with -sSUPPORT_BIG_ENDIAN to bypass)';
  692. })();
  693. // end include: runtime_assertions.js
  694. var __ATPRERUN__ = []; // functions called before the runtime is initialized
  695. var __ATINIT__ = []; // functions called during startup
  696. var __ATMAIN__ = []; // functions called when main() is to be run
  697. var __ATEXIT__ = []; // functions called during shutdown
  698. var __ATPOSTRUN__ = []; // functions called after the main() is called
  699. var runtimeInitialized = false;
  700. var runtimeExited = false;
  701. var runtimeKeepaliveCounter = 0;
  702. function keepRuntimeAlive() {
  703. return noExitRuntime || runtimeKeepaliveCounter > 0;
  704. }
  705. function preRun() {
  706. if (Module['preRun']) {
  707. if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];
  708. while (Module['preRun'].length) {
  709. addOnPreRun(Module['preRun'].shift());
  710. }
  711. }
  712. callRuntimeCallbacks(__ATPRERUN__);
  713. }
  714. function initRuntime() {
  715. assert(!runtimeInitialized);
  716. runtimeInitialized = true;
  717. checkStackCookie();
  718. if (!Module["noFSInit"] && !FS.init.initialized)
  719. FS.init();
  720. FS.ignorePermissions = false;
  721. TTY.init();
  722. callRuntimeCallbacks(__ATINIT__);
  723. }
  724. function preMain() {
  725. checkStackCookie();
  726. callRuntimeCallbacks(__ATMAIN__);
  727. }
  728. function exitRuntime() {
  729. // ASYNCIFY cannot be used once the runtime starts shutting down.
  730. Asyncify.state = Asyncify.State.Disabled;
  731. checkStackCookie();
  732. ___funcs_on_exit(); // Native atexit() functions
  733. callRuntimeCallbacks(__ATEXIT__);
  734. FS.quit();
  735. TTY.shutdown();
  736. runtimeExited = true;
  737. }
  738. function postRun() {
  739. checkStackCookie();
  740. if (Module['postRun']) {
  741. if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];
  742. while (Module['postRun'].length) {
  743. addOnPostRun(Module['postRun'].shift());
  744. }
  745. }
  746. callRuntimeCallbacks(__ATPOSTRUN__);
  747. }
  748. function addOnPreRun(cb) {
  749. __ATPRERUN__.unshift(cb);
  750. }
  751. function addOnInit(cb) {
  752. __ATINIT__.unshift(cb);
  753. }
  754. function addOnPreMain(cb) {
  755. __ATMAIN__.unshift(cb);
  756. }
  757. function addOnExit(cb) {
  758. __ATEXIT__.unshift(cb);
  759. }
  760. function addOnPostRun(cb) {
  761. __ATPOSTRUN__.unshift(cb);
  762. }
  763. // include: runtime_math.js
  764. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul
  765. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround
  766. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32
  767. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc
  768. assert(Math.imul, 'This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
  769. assert(Math.fround, 'This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
  770. assert(Math.clz32, 'This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
  771. assert(Math.trunc, 'This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
  772. // end include: runtime_math.js
  773. // A counter of dependencies for calling run(). If we need to
  774. // do asynchronous work before running, increment this and
  775. // decrement it. Incrementing must happen in a place like
  776. // Module.preRun (used by emcc to add file preloading).
  777. // Note that you can add dependencies in preRun, even though
  778. // it happens right before run - run will be postponed until
  779. // the dependencies are met.
  780. var runDependencies = 0;
  781. var runDependencyWatcher = null;
  782. var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled
  783. var runDependencyTracking = {};
  784. function getUniqueRunDependency(id) {
  785. var orig = id;
  786. while (1) {
  787. if (!runDependencyTracking[id]) return id;
  788. id = orig + Math.random();
  789. }
  790. }
  791. function addRunDependency(id) {
  792. runDependencies++;
  793. if (Module['monitorRunDependencies']) {
  794. Module['monitorRunDependencies'](runDependencies);
  795. }
  796. if (id) {
  797. assert(!runDependencyTracking[id]);
  798. runDependencyTracking[id] = 1;
  799. if (runDependencyWatcher === null && typeof setInterval != 'undefined') {
  800. // Check for missing dependencies every few seconds
  801. runDependencyWatcher = setInterval(function() {
  802. if (ABORT) {
  803. clearInterval(runDependencyWatcher);
  804. runDependencyWatcher = null;
  805. return;
  806. }
  807. var shown = false;
  808. for (var dep in runDependencyTracking) {
  809. if (!shown) {
  810. shown = true;
  811. err('still waiting on run dependencies:');
  812. }
  813. err('dependency: ' + dep);
  814. }
  815. if (shown) {
  816. err('(end of list)');
  817. }
  818. }, 10000);
  819. }
  820. } else {
  821. err('warning: run dependency added without ID');
  822. }
  823. }
  824. function removeRunDependency(id) {
  825. runDependencies--;
  826. if (Module['monitorRunDependencies']) {
  827. Module['monitorRunDependencies'](runDependencies);
  828. }
  829. if (id) {
  830. assert(runDependencyTracking[id]);
  831. delete runDependencyTracking[id];
  832. } else {
  833. err('warning: run dependency removed without ID');
  834. }
  835. if (runDependencies == 0) {
  836. if (runDependencyWatcher !== null) {
  837. clearInterval(runDependencyWatcher);
  838. runDependencyWatcher = null;
  839. }
  840. if (dependenciesFulfilled) {
  841. var callback = dependenciesFulfilled;
  842. dependenciesFulfilled = null;
  843. callback(); // can add another dependenciesFulfilled
  844. }
  845. }
  846. }
  847. /** @param {string|number=} what */
  848. function abort(what) {
  849. if (Module['onAbort']) {
  850. Module['onAbort'](what);
  851. }
  852. what = 'Aborted(' + what + ')';
  853. // TODO(sbc): Should we remove printing and leave it up to whoever
  854. // catches the exception?
  855. err(what);
  856. ABORT = true;
  857. EXITSTATUS = 1;
  858. if (what.indexOf('RuntimeError: unreachable') >= 0) {
  859. what += '. "unreachable" may be due to ASYNCIFY_STACK_SIZE not being large enough (try increasing it)';
  860. }
  861. // Use a wasm runtime error, because a JS error might be seen as a foreign
  862. // exception, which means we'd run destructors on it. We need the error to
  863. // simply make the program stop.
  864. // FIXME This approach does not work in Wasm EH because it currently does not assume
  865. // all RuntimeErrors are from traps; it decides whether a RuntimeError is from
  866. // a trap or not based on a hidden field within the object. So at the moment
  867. // we don't have a way of throwing a wasm trap from JS. TODO Make a JS API that
  868. // allows this in the wasm spec.
  869. // Suppress closure compiler warning here. Closure compiler's builtin extern
  870. // defintion for WebAssembly.RuntimeError claims it takes no arguments even
  871. // though it can.
  872. // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure gets fixed.
  873. /** @suppress {checkTypes} */
  874. var e = new WebAssembly.RuntimeError(what);
  875. // Throw the error whether or not MODULARIZE is set because abort is used
  876. // in code paths apart from instantiation where an exception is expected
  877. // to be thrown when abort is called.
  878. throw e;
  879. }
  880. // {{MEM_INITIALIZER}}
  881. // include: memoryprofiler.js
  882. // end include: memoryprofiler.js
  883. // include: URIUtils.js
  884. // Prefix of data URIs emitted by SINGLE_FILE and related options.
  885. var dataURIPrefix = 'data:application/octet-stream;base64,';
  886. // Indicates whether filename is a base64 data URI.
  887. function isDataURI(filename) {
  888. // Prefix of data URIs emitted by SINGLE_FILE and related options.
  889. return filename.startsWith(dataURIPrefix);
  890. }
  891. // Indicates whether filename is delivered via file protocol (as opposed to http/https)
  892. function isFileURI(filename) {
  893. return filename.startsWith('file://');
  894. }
  895. // end include: URIUtils.js
  896. /** @param {boolean=} fixedasm */
  897. function createExportWrapper(name, fixedasm) {
  898. return function() {
  899. var displayName = name;
  900. var asm = fixedasm;
  901. if (!fixedasm) {
  902. asm = Module['asm'];
  903. }
  904. assert(runtimeInitialized, 'native function `' + displayName + '` called before runtime initialization');
  905. assert(!runtimeExited, 'native function `' + displayName + '` called after runtime exit (use NO_EXIT_RUNTIME to keep it alive after main() exits)');
  906. if (!asm[name]) {
  907. assert(asm[name], 'exported native function `' + displayName + '` not found');
  908. }
  909. return asm[name].apply(null, arguments);
  910. };
  911. }
  912. var wasmBinaryFile;
  913. wasmBinaryFile = 'tngp.wasm';
  914. if (!isDataURI(wasmBinaryFile)) {
  915. wasmBinaryFile = locateFile(wasmBinaryFile);
  916. }
  917. function getBinary(file) {
  918. try {
  919. if (file == wasmBinaryFile && wasmBinary) {
  920. return new Uint8Array(wasmBinary);
  921. }
  922. if (readBinary) {
  923. return readBinary(file);
  924. }
  925. throw "both async and sync fetching of the wasm failed";
  926. }
  927. catch (err) {
  928. abort(err);
  929. }
  930. }
  931. function getBinaryPromise() {
  932. // If we don't have the binary yet, try to to load it asynchronously.
  933. // Fetch has some additional restrictions over XHR, like it can't be used on a file:// url.
  934. // See https://github.com/github/fetch/pull/92#issuecomment-140665932
  935. // Cordova or Electron apps are typically loaded from a file:// url.
  936. // So use fetch if it is available and the url is not a file, otherwise fall back to XHR.
  937. if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER)) {
  938. if (typeof fetch == 'function'
  939. && !isFileURI(wasmBinaryFile)
  940. ) {
  941. return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function(response) {
  942. if (!response['ok']) {
  943. throw "failed to load wasm binary file at '" + wasmBinaryFile + "'";
  944. }
  945. return response['arrayBuffer']();
  946. }).catch(function () {
  947. return getBinary(wasmBinaryFile);
  948. });
  949. }
  950. else {
  951. if (readAsync) {
  952. // fetch is not available or url is file => try XHR (readAsync uses XHR internally)
  953. return new Promise(function(resolve, reject) {
  954. readAsync(wasmBinaryFile, function(response) { resolve(new Uint8Array(/** @type{!ArrayBuffer} */(response))) }, reject)
  955. });
  956. }
  957. }
  958. }
  959. // Otherwise, getBinary should be able to get it synchronously
  960. return Promise.resolve().then(function() { return getBinary(wasmBinaryFile); });
  961. }
  962. // Create the wasm instance.
  963. // Receives the wasm imports, returns the exports.
  964. function createWasm() {
  965. // prepare imports
  966. var info = {
  967. 'env': asmLibraryArg,
  968. 'wasi_snapshot_preview1': asmLibraryArg,
  969. };
  970. // Load the wasm module and create an instance of using native support in the JS engine.
  971. // handle a generated wasm instance, receiving its exports and
  972. // performing other necessary setup
  973. /** @param {WebAssembly.Module=} module*/
  974. function receiveInstance(instance, module) {
  975. var exports = instance.exports;
  976. exports = Asyncify.instrumentWasmExports(exports);
  977. Module['asm'] = exports;
  978. wasmMemory = Module['asm']['memory'];
  979. assert(wasmMemory, "memory not found in wasm exports");
  980. // This assertion doesn't hold when emscripten is run in --post-link
  981. // mode.
  982. // TODO(sbc): Read INITIAL_MEMORY out of the wasm file in post-link mode.
  983. //assert(wasmMemory.buffer.byteLength === 16777216);
  984. updateGlobalBufferAndViews(wasmMemory.buffer);
  985. wasmTable = Module['asm']['__indirect_function_table'];
  986. assert(wasmTable, "table not found in wasm exports");
  987. addOnInit(Module['asm']['__wasm_call_ctors']);
  988. removeRunDependency('wasm-instantiate');
  989. }
  990. // we can't run yet (except in a pthread, where we have a custom sync instantiator)
  991. addRunDependency('wasm-instantiate');
  992. // Prefer streaming instantiation if available.
  993. // Async compilation can be confusing when an error on the page overwrites Module
  994. // (for example, if the order of elements is wrong, and the one defining Module is
  995. // later), so we save Module and check it later.
  996. var trueModule = Module;
  997. function receiveInstantiationResult(result) {
  998. // 'result' is a ResultObject object which has both the module and instance.
  999. // receiveInstance() will swap in the exports (to Module.asm) so they can be called
  1000. assert(Module === trueModule, 'the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?');
  1001. trueModule = null;
  1002. // 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.
  1003. // When the regression is fixed, can restore the above USE_PTHREADS-enabled path.
  1004. receiveInstance(result['instance']);
  1005. }
  1006. function instantiateArrayBuffer(receiver) {
  1007. return getBinaryPromise().then(function(binary) {
  1008. return WebAssembly.instantiate(binary, info);
  1009. }).then(function (instance) {
  1010. return instance;
  1011. }).then(receiver, function(reason) {
  1012. err('failed to asynchronously prepare wasm: ' + reason);
  1013. // Warn on some common problems.
  1014. if (isFileURI(wasmBinaryFile)) {
  1015. 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');
  1016. }
  1017. abort(reason);
  1018. });
  1019. }
  1020. function instantiateAsync() {
  1021. if (!wasmBinary &&
  1022. typeof WebAssembly.instantiateStreaming == 'function' &&
  1023. !isDataURI(wasmBinaryFile) &&
  1024. // Don't use streaming for file:// delivered objects in a webview, fetch them synchronously.
  1025. !isFileURI(wasmBinaryFile) &&
  1026. // Avoid instantiateStreaming() on Node.js environment for now, as while
  1027. // Node.js v18.1.0 implements it, it does not have a full fetch()
  1028. // implementation yet.
  1029. //
  1030. // Reference:
  1031. // https://github.com/emscripten-core/emscripten/pull/16917
  1032. !ENVIRONMENT_IS_NODE &&
  1033. typeof fetch == 'function') {
  1034. return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function(response) {
  1035. // Suppress closure warning here since the upstream definition for
  1036. // instantiateStreaming only allows Promise<Repsponse> rather than
  1037. // an actual Response.
  1038. // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure is fixed.
  1039. /** @suppress {checkTypes} */
  1040. var result = WebAssembly.instantiateStreaming(response, info);
  1041. return result.then(
  1042. receiveInstantiationResult,
  1043. function(reason) {
  1044. // We expect the most common failure cause to be a bad MIME type for the binary,
  1045. // in which case falling back to ArrayBuffer instantiation should work.
  1046. err('wasm streaming compile failed: ' + reason);
  1047. err('falling back to ArrayBuffer instantiation');
  1048. return instantiateArrayBuffer(receiveInstantiationResult);
  1049. });
  1050. });
  1051. } else {
  1052. return instantiateArrayBuffer(receiveInstantiationResult);
  1053. }
  1054. }
  1055. // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback
  1056. // to manually instantiate the Wasm module themselves. This allows pages to run the instantiation parallel
  1057. // to any other async startup actions they are performing.
  1058. // Also pthreads and wasm workers initialize the wasm instance through this path.
  1059. if (Module['instantiateWasm']) {
  1060. try {
  1061. var exports = Module['instantiateWasm'](info, receiveInstance);
  1062. exports = Asyncify.instrumentWasmExports(exports);
  1063. return exports;
  1064. } catch(e) {
  1065. err('Module.instantiateWasm callback failed with error: ' + e);
  1066. return false;
  1067. }
  1068. }
  1069. instantiateAsync();
  1070. return {}; // no exports yet; we'll fill them in later
  1071. }
  1072. // Globals used by JS i64 conversions (see makeSetValue)
  1073. var tempDouble;
  1074. var tempI64;
  1075. // === Body ===
  1076. var ASM_CONSTS = {
  1077. 6391040: () => { tngoffset = 0; },
  1078. 6391057: ($0, $1) => { tngoffset = $1 * 2147483648 + $0; },
  1079. 6391093: ($0) => { alert('TirNanoG\r\n\r\n'+UTF8ToString($0)); },
  1080. 6391143: ($0) => { document.location.href=UTF8ToString($0); },
  1081. 6391186: () => { return ln.charCodeAt(1) * 256 + ln.charCodeAt(0); },
  1082. 6391240: () => { document.getElementById("load").style.display="none";document.getElementById("canvas").style.display="block"; },
  1083. 6391354: () => { return window.innerWidth; },
  1084. 6391384: () => { return window.innerHeight; },
  1085. 6391415: ($0) => { var str = UTF8ToString($0) + '\n\n' + 'Abort/Retry/Ignore/AlwaysIgnore? [ariA] :'; var reply = window.prompt(str, "i"); if (reply === null) { reply = "i"; } return allocate(intArrayFromString(reply), 'i8', ALLOC_NORMAL); },
  1086. 6391640: () => { if (typeof(AudioContext) !== 'undefined') { return true; } else if (typeof(webkitAudioContext) !== 'undefined') { return true; } return false; },
  1087. 6391787: () => { if ((typeof(navigator.mediaDevices) !== 'undefined') && (typeof(navigator.mediaDevices.getUserMedia) !== 'undefined')) { return true; } else if (typeof(navigator.webkitGetUserMedia) !== 'undefined') { return true; } return false; },
  1088. 6392021: ($0) => { if(typeof(Module['SDL2']) === 'undefined') { Module['SDL2'] = {}; } var SDL2 = Module['SDL2']; if (!$0) { SDL2.audio = {}; } else { SDL2.capture = {}; } if (!SDL2.audioContext) { if (typeof(AudioContext) !== 'undefined') { SDL2.audioContext = new AudioContext(); } else if (typeof(webkitAudioContext) !== 'undefined') { SDL2.audioContext = new webkitAudioContext(); } if (SDL2.audioContext) { autoResumeAudioContext(SDL2.audioContext); } } return SDL2.audioContext === undefined ? -1 : 0; },
  1089. 6392514: () => { var SDL2 = Module['SDL2']; return SDL2.audioContext.sampleRate; },
  1090. 6392582: ($0, $1, $2, $3) => { var SDL2 = Module['SDL2']; var have_microphone = function(stream) { if (SDL2.capture.silenceTimer !== undefined) { clearTimeout(SDL2.capture.silenceTimer); SDL2.capture.silenceTimer = undefined; } SDL2.capture.mediaStreamNode = SDL2.audioContext.createMediaStreamSource(stream); SDL2.capture.scriptProcessorNode = SDL2.audioContext.createScriptProcessor($1, $0, 1); SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) { if ((SDL2 === undefined) || (SDL2.capture === undefined)) { return; } audioProcessingEvent.outputBuffer.getChannelData(0).fill(0.0); SDL2.capture.currentCaptureBuffer = audioProcessingEvent.inputBuffer; dynCall('vi', $2, [$3]); }; SDL2.capture.mediaStreamNode.connect(SDL2.capture.scriptProcessorNode); SDL2.capture.scriptProcessorNode.connect(SDL2.audioContext.destination); SDL2.capture.stream = stream; }; var no_microphone = function(error) { }; SDL2.capture.silenceBuffer = SDL2.audioContext.createBuffer($0, $1, SDL2.audioContext.sampleRate); SDL2.capture.silenceBuffer.getChannelData(0).fill(0.0); var silence_callback = function() { SDL2.capture.currentCaptureBuffer = SDL2.capture.silenceBuffer; dynCall('vi', $2, [$3]); }; SDL2.capture.silenceTimer = setTimeout(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1000); if ((navigator.mediaDevices !== undefined) && (navigator.mediaDevices.getUserMedia !== undefined)) { navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then(have_microphone).catch(no_microphone); } else if (navigator.webkitGetUserMedia !== undefined) { navigator.webkitGetUserMedia({ audio: true, video: false }, have_microphone, no_microphone); } },
  1091. 6394234: ($0, $1, $2, $3) => { var SDL2 = Module['SDL2']; SDL2.audio.scriptProcessorNode = SDL2.audioContext['createScriptProcessor']($1, 0, $0); SDL2.audio.scriptProcessorNode['onaudioprocess'] = function (e) { if ((SDL2 === undefined) || (SDL2.audio === undefined)) { return; } SDL2.audio.currentOutputBuffer = e['outputBuffer']; dynCall('vi', $2, [$3]); }; SDL2.audio.scriptProcessorNode['connect'](SDL2.audioContext['destination']); },
  1092. 6394644: ($0, $1) => { var SDL2 = Module['SDL2']; var numChannels = SDL2.capture.currentCaptureBuffer.numberOfChannels; for (var c = 0; c < numChannels; ++c) { var channelData = SDL2.capture.currentCaptureBuffer.getChannelData(c); if (channelData.length != $1) { throw 'Web Audio capture buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!'; } if (numChannels == 1) { for (var j = 0; j < $1; ++j) { setValue($0 + (j * 4), channelData[j], 'float'); } } else { for (var j = 0; j < $1; ++j) { setValue($0 + (((j * numChannels) + c) * 4), channelData[j], 'float'); } } } },
  1093. 6395249: ($0, $1) => { var SDL2 = Module['SDL2']; var numChannels = SDL2.audio.currentOutputBuffer['numberOfChannels']; for (var c = 0; c < numChannels; ++c) { var channelData = SDL2.audio.currentOutputBuffer['getChannelData'](c); if (channelData.length != $1) { throw 'Web Audio output buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!'; } for (var j = 0; j < $1; ++j) { channelData[j] = HEAPF32[$0 + ((j*numChannels + c) << 2) >> 2]; } } },
  1094. 6395729: ($0) => { var SDL2 = Module['SDL2']; if ($0) { if (SDL2.capture.silenceTimer !== undefined) { clearTimeout(SDL2.capture.silenceTimer); } if (SDL2.capture.stream !== undefined) { var tracks = SDL2.capture.stream.getAudioTracks(); for (var i = 0; i < tracks.length; i++) { SDL2.capture.stream.removeTrack(tracks[i]); } SDL2.capture.stream = undefined; } if (SDL2.capture.scriptProcessorNode !== undefined) { SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) {}; SDL2.capture.scriptProcessorNode.disconnect(); SDL2.capture.scriptProcessorNode = undefined; } if (SDL2.capture.mediaStreamNode !== undefined) { SDL2.capture.mediaStreamNode.disconnect(); SDL2.capture.mediaStreamNode = undefined; } if (SDL2.capture.silenceBuffer !== undefined) { SDL2.capture.silenceBuffer = undefined } SDL2.capture = undefined; } else { if (SDL2.audio.scriptProcessorNode != undefined) { SDL2.audio.scriptProcessorNode.disconnect(); SDL2.audio.scriptProcessorNode = undefined; } SDL2.audio = undefined; } if ((SDL2.audioContext !== undefined) && (SDL2.audio === undefined) && (SDL2.capture === undefined)) { SDL2.audioContext.close(); SDL2.audioContext = undefined; } },
  1095. 6396901: ($0, $1, $2) => { var w = $0; var h = $1; var pixels = $2; if (!Module['SDL2']) Module['SDL2'] = {}; var SDL2 = Module['SDL2']; if (SDL2.ctxCanvas !== Module['canvas']) { SDL2.ctx = Module['createContext'](Module['canvas'], false, true); SDL2.ctxCanvas = Module['canvas']; } if (SDL2.w !== w || SDL2.h !== h || SDL2.imageCtx !== SDL2.ctx) { SDL2.image = SDL2.ctx.createImageData(w, h); SDL2.w = w; SDL2.h = h; SDL2.imageCtx = SDL2.ctx; } var data = SDL2.image.data; var src = pixels >> 2; var dst = 0; var num; if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) { num = data.length; while (dst < num) { var val = HEAP32[src]; data[dst ] = val & 0xff; data[dst+1] = (val >> 8) & 0xff; data[dst+2] = (val >> 16) & 0xff; data[dst+3] = 0xff; src++; dst += 4; } } else { if (SDL2.data32Data !== data) { SDL2.data32 = new Int32Array(data.buffer); SDL2.data8 = new Uint8Array(data.buffer); SDL2.data32Data = data; } var data32 = SDL2.data32; num = data32.length; data32.set(HEAP32.subarray(src, src + num)); var data8 = SDL2.data8; var i = 3; var j = i + 4*num; if (num % 8 == 0) { while (i < j) { data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; } } else { while (i < j) { data8[i] = 0xff; i = i + 4 | 0; } } } SDL2.ctx.putImageData(SDL2.image, 0, 0); },
  1096. 6398370: ($0, $1, $2, $3, $4) => { var w = $0; var h = $1; var hot_x = $2; var hot_y = $3; var pixels = $4; var canvas = document.createElement("canvas"); canvas.width = w; canvas.height = h; var ctx = canvas.getContext("2d"); var image = ctx.createImageData(w, h); var data = image.data; var src = pixels >> 2; var dst = 0; var num; if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) { num = data.length; while (dst < num) { var val = HEAP32[src]; data[dst ] = val & 0xff; data[dst+1] = (val >> 8) & 0xff; data[dst+2] = (val >> 16) & 0xff; data[dst+3] = (val >> 24) & 0xff; src++; dst += 4; } } else { var data32 = new Int32Array(data.buffer); num = data32.length; data32.set(HEAP32.subarray(src, src + num)); } ctx.putImageData(image, 0, 0); var url = hot_x === 0 && hot_y === 0 ? "url(" + canvas.toDataURL() + "), auto" : "url(" + canvas.toDataURL() + ") " + hot_x + " " + hot_y + ", auto"; var urlBuf = _malloc(url.length + 1); stringToUTF8(url, urlBuf, url.length + 1); return urlBuf; },
  1097. 6399359: ($0) => { if (Module['canvas']) { Module['canvas'].style['cursor'] = UTF8ToString($0); } },
  1098. 6399442: () => { if (Module['canvas']) { Module['canvas'].style['cursor'] = 'none'; } },
  1099. 6399511: () => { return window.innerWidth; },
  1100. 6399541: () => { return window.innerHeight; }
  1101. };
  1102. function __asyncjs__emscriptmadness(buf,size) { return Asyncify.handleAsync(async () => { if(tngfile == undefined) return 0; var blob = tngfile.slice(tngoffset, tngoffset + size); var ret = await new Promise((resolve, reject) => { const reader = new FileReader(); reader.onloadend = () => resolve(reader.result); reader.readAsArrayBuffer(blob); }); if(ret == undefined || ret.byteLength < 1) return 0; var u8data = new Uint8Array(ret, 0, ret.byteLength); Module.HEAPU8.set(u8data, buf); tngoffset += ret.byteLength; return ret.byteLength; }); }
  1103. /** @constructor */
  1104. function ExitStatus(status) {
  1105. this.name = 'ExitStatus';
  1106. this.message = 'Program terminated with exit(' + status + ')';
  1107. this.status = status;
  1108. }
  1109. function listenOnce(object, event, func) {
  1110. object.addEventListener(event, func, { 'once': true });
  1111. }
  1112. /** @param {Object=} elements */
  1113. function autoResumeAudioContext(ctx, elements) {
  1114. if (!elements) {
  1115. elements = [document, document.getElementById('canvas')];
  1116. }
  1117. ['keydown', 'mousedown', 'touchstart'].forEach(function(event) {
  1118. elements.forEach(function(element) {
  1119. if (element) {
  1120. listenOnce(element, event, () => {
  1121. if (ctx.state === 'suspended') ctx.resume();
  1122. });
  1123. }
  1124. });
  1125. });
  1126. }
  1127. function callRuntimeCallbacks(callbacks) {
  1128. while (callbacks.length > 0) {
  1129. // Pass the module as the first argument.
  1130. callbacks.shift()(Module);
  1131. }
  1132. }
  1133. function dynCallLegacy(sig, ptr, args) {
  1134. assert(('dynCall_' + sig) in Module, 'bad function pointer type - dynCall function not found for sig \'' + sig + '\'');
  1135. if (args && args.length) {
  1136. // j (64-bit integer) must be passed in as two numbers [low 32, high 32].
  1137. assert(args.length === sig.substring(1).replace(/j/g, '--').length);
  1138. } else {
  1139. assert(sig.length == 1);
  1140. }
  1141. var f = Module['dynCall_' + sig];
  1142. return args && args.length ? f.apply(null, [ptr].concat(args)) : f.call(null, ptr);
  1143. }
  1144. var wasmTableMirror = [];
  1145. function getWasmTableEntry(funcPtr) {
  1146. var func = wasmTableMirror[funcPtr];
  1147. if (!func) {
  1148. if (funcPtr >= wasmTableMirror.length) wasmTableMirror.length = funcPtr + 1;
  1149. wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr);
  1150. }
  1151. assert(wasmTable.get(funcPtr) == func, "JavaScript-side Wasm function table mirror is out of date!");
  1152. return func;
  1153. }
  1154. /** @param {Object=} args */
  1155. function dynCall(sig, ptr, args) {
  1156. return dynCallLegacy(sig, ptr, args);
  1157. }
  1158. /**
  1159. * @param {number} ptr
  1160. * @param {string} type
  1161. */
  1162. function getValue(ptr, type = 'i8') {
  1163. if (type.endsWith('*')) type = '*';
  1164. switch (type) {
  1165. case 'i1': return HEAP8[((ptr)>>0)];
  1166. case 'i8': return HEAP8[((ptr)>>0)];
  1167. case 'i16': return HEAP16[((ptr)>>1)];
  1168. case 'i32': return HEAP32[((ptr)>>2)];
  1169. case 'i64': return HEAP64[((ptr)>>3)];
  1170. case 'float': return HEAPF32[((ptr)>>2)];
  1171. case 'double': return HEAPF64[((ptr)>>3)];
  1172. case '*': return HEAPU32[((ptr)>>2)];
  1173. default: abort('invalid type for getValue: ' + type);
  1174. }
  1175. return null;
  1176. }
  1177. function ptrToString(ptr) {
  1178. return '0x' + ptr.toString(16).padStart(8, '0');
  1179. }
  1180. /**
  1181. * @param {number} ptr
  1182. * @param {number} value
  1183. * @param {string} type
  1184. */
  1185. function setValue(ptr, value, type = 'i8') {
  1186. if (type.endsWith('*')) type = '*';
  1187. switch (type) {
  1188. case 'i1': HEAP8[((ptr)>>0)] = value; break;
  1189. case 'i8': HEAP8[((ptr)>>0)] = value; break;
  1190. case 'i16': HEAP16[((ptr)>>1)] = value; break;
  1191. case 'i32': HEAP32[((ptr)>>2)] = value; break;
  1192. case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[((ptr)>>2)] = tempI64[0],HEAP32[(((ptr)+(4))>>2)] = tempI64[1]); break;
  1193. case 'float': HEAPF32[((ptr)>>2)] = value; break;
  1194. case 'double': HEAPF64[((ptr)>>3)] = value; break;
  1195. case '*': HEAPU32[((ptr)>>2)] = value; break;
  1196. default: abort('invalid type for setValue: ' + type);
  1197. }
  1198. }
  1199. function warnOnce(text) {
  1200. if (!warnOnce.shown) warnOnce.shown = {};
  1201. if (!warnOnce.shown[text]) {
  1202. warnOnce.shown[text] = 1;
  1203. if (ENVIRONMENT_IS_NODE) text = 'warning: ' + text;
  1204. err(text);
  1205. }
  1206. }
  1207. function ___assert_fail(condition, filename, line, func) {
  1208. abort('Assertion failed: ' + UTF8ToString(condition) + ', at: ' + [filename ? UTF8ToString(filename) : 'unknown filename', line, func ? UTF8ToString(func) : 'unknown function']);
  1209. }
  1210. function setErrNo(value) {
  1211. HEAP32[((___errno_location())>>2)] = value;
  1212. return value;
  1213. }
  1214. var PATH = {isAbs:(path) => path.charAt(0) === '/',splitPath:(filename) => {
  1215. var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
  1216. return splitPathRe.exec(filename).slice(1);
  1217. },normalizeArray:(parts, allowAboveRoot) => {
  1218. // if the path tries to go above the root, `up` ends up > 0
  1219. var up = 0;
  1220. for (var i = parts.length - 1; i >= 0; i--) {
  1221. var last = parts[i];
  1222. if (last === '.') {
  1223. parts.splice(i, 1);
  1224. } else if (last === '..') {
  1225. parts.splice(i, 1);
  1226. up++;
  1227. } else if (up) {
  1228. parts.splice(i, 1);
  1229. up--;
  1230. }
  1231. }
  1232. // if the path is allowed to go above the root, restore leading ..s
  1233. if (allowAboveRoot) {
  1234. for (; up; up--) {
  1235. parts.unshift('..');
  1236. }
  1237. }
  1238. return parts;
  1239. },normalize:(path) => {
  1240. var isAbsolute = PATH.isAbs(path),
  1241. trailingSlash = path.substr(-1) === '/';
  1242. // Normalize the path
  1243. path = PATH.normalizeArray(path.split('/').filter((p) => !!p), !isAbsolute).join('/');
  1244. if (!path && !isAbsolute) {
  1245. path = '.';
  1246. }
  1247. if (path && trailingSlash) {
  1248. path += '/';
  1249. }
  1250. return (isAbsolute ? '/' : '') + path;
  1251. },dirname:(path) => {
  1252. var result = PATH.splitPath(path),
  1253. root = result[0],
  1254. dir = result[1];
  1255. if (!root && !dir) {
  1256. // No dirname whatsoever
  1257. return '.';
  1258. }
  1259. if (dir) {
  1260. // It has a dirname, strip trailing slash
  1261. dir = dir.substr(0, dir.length - 1);
  1262. }
  1263. return root + dir;
  1264. },basename:(path) => {
  1265. // EMSCRIPTEN return '/'' for '/', not an empty string
  1266. if (path === '/') return '/';
  1267. path = PATH.normalize(path);
  1268. path = path.replace(/\/$/, "");
  1269. var lastSlash = path.lastIndexOf('/');
  1270. if (lastSlash === -1) return path;
  1271. return path.substr(lastSlash+1);
  1272. },join:function() {
  1273. var paths = Array.prototype.slice.call(arguments);
  1274. return PATH.normalize(paths.join('/'));
  1275. },join2:(l, r) => {
  1276. return PATH.normalize(l + '/' + r);
  1277. }};
  1278. function getRandomDevice() {
  1279. if (typeof crypto == 'object' && typeof crypto['getRandomValues'] == 'function') {
  1280. // for modern web browsers
  1281. var randomBuffer = new Uint8Array(1);
  1282. return () => { crypto.getRandomValues(randomBuffer); return randomBuffer[0]; };
  1283. } else
  1284. if (ENVIRONMENT_IS_NODE) {
  1285. // for nodejs with or without crypto support included
  1286. try {
  1287. var crypto_module = require('crypto');
  1288. // nodejs has crypto support
  1289. return () => crypto_module['randomBytes'](1)[0];
  1290. } catch (e) {
  1291. // nodejs doesn't have crypto support
  1292. }
  1293. }
  1294. // we couldn't find a proper implementation, as Math.random() is not suitable for /dev/random, see emscripten-core/emscripten/pull/7096
  1295. return () => abort("no cryptographic support found for randomDevice. consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: function(array) { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } };");
  1296. }
  1297. var PATH_FS = {resolve:function() {
  1298. var resolvedPath = '',
  1299. resolvedAbsolute = false;
  1300. for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
  1301. var path = (i >= 0) ? arguments[i] : FS.cwd();
  1302. // Skip empty and invalid entries
  1303. if (typeof path != 'string') {
  1304. throw new TypeError('Arguments to path.resolve must be strings');
  1305. } else if (!path) {
  1306. return ''; // an invalid portion invalidates the whole thing
  1307. }
  1308. resolvedPath = path + '/' + resolvedPath;
  1309. resolvedAbsolute = PATH.isAbs(path);
  1310. }
  1311. // At this point the path should be resolved to a full absolute path, but
  1312. // handle relative paths to be safe (might happen when process.cwd() fails)
  1313. resolvedPath = PATH.normalizeArray(resolvedPath.split('/').filter((p) => !!p), !resolvedAbsolute).join('/');
  1314. return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
  1315. },relative:(from, to) => {
  1316. from = PATH_FS.resolve(from).substr(1);
  1317. to = PATH_FS.resolve(to).substr(1);
  1318. function trim(arr) {
  1319. var start = 0;
  1320. for (; start < arr.length; start++) {
  1321. if (arr[start] !== '') break;
  1322. }
  1323. var end = arr.length - 1;
  1324. for (; end >= 0; end--) {
  1325. if (arr[end] !== '') break;
  1326. }
  1327. if (start > end) return [];
  1328. return arr.slice(start, end - start + 1);
  1329. }
  1330. var fromParts = trim(from.split('/'));
  1331. var toParts = trim(to.split('/'));
  1332. var length = Math.min(fromParts.length, toParts.length);
  1333. var samePartsLength = length;
  1334. for (var i = 0; i < length; i++) {
  1335. if (fromParts[i] !== toParts[i]) {
  1336. samePartsLength = i;
  1337. break;
  1338. }
  1339. }
  1340. var outputParts = [];
  1341. for (var i = samePartsLength; i < fromParts.length; i++) {
  1342. outputParts.push('..');
  1343. }
  1344. outputParts = outputParts.concat(toParts.slice(samePartsLength));
  1345. return outputParts.join('/');
  1346. }};
  1347. /** @type {function(string, boolean=, number=)} */
  1348. function intArrayFromString(stringy, dontAddNull, length) {
  1349. var len = length > 0 ? length : lengthBytesUTF8(stringy)+1;
  1350. var u8array = new Array(len);
  1351. var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length);
  1352. if (dontAddNull) u8array.length = numBytesWritten;
  1353. return u8array;
  1354. }
  1355. var TTY = {ttys:[],init:function () {
  1356. // https://github.com/emscripten-core/emscripten/pull/1555
  1357. // if (ENVIRONMENT_IS_NODE) {
  1358. // // currently, FS.init does not distinguish if process.stdin is a file or TTY
  1359. // // device, it always assumes it's a TTY device. because of this, we're forcing
  1360. // // process.stdin to UTF8 encoding to at least make stdin reading compatible
  1361. // // with text files until FS.init can be refactored.
  1362. // process['stdin']['setEncoding']('utf8');
  1363. // }
  1364. },shutdown:function() {
  1365. // https://github.com/emscripten-core/emscripten/pull/1555
  1366. // if (ENVIRONMENT_IS_NODE) {
  1367. // // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)?
  1368. // // 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
  1369. // // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists?
  1370. // // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle
  1371. // // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call
  1372. // process['stdin']['pause']();
  1373. // }
  1374. },register:function(dev, ops) {
  1375. TTY.ttys[dev] = { input: [], output: [], ops: ops };
  1376. FS.registerDevice(dev, TTY.stream_ops);
  1377. },stream_ops:{open:function(stream) {
  1378. var tty = TTY.ttys[stream.node.rdev];
  1379. if (!tty) {
  1380. throw new FS.ErrnoError(43);
  1381. }
  1382. stream.tty = tty;
  1383. stream.seekable = false;
  1384. },close:function(stream) {
  1385. // flush any pending line data
  1386. stream.tty.ops.fsync(stream.tty);
  1387. },fsync:function(stream) {
  1388. stream.tty.ops.fsync(stream.tty);
  1389. },read:function(stream, buffer, offset, length, pos /* ignored */) {
  1390. if (!stream.tty || !stream.tty.ops.get_char) {
  1391. throw new FS.ErrnoError(60);
  1392. }
  1393. var bytesRead = 0;
  1394. for (var i = 0; i < length; i++) {
  1395. var result;
  1396. try {
  1397. result = stream.tty.ops.get_char(stream.tty);
  1398. } catch (e) {
  1399. throw new FS.ErrnoError(29);
  1400. }
  1401. if (result === undefined && bytesRead === 0) {
  1402. throw new FS.ErrnoError(6);
  1403. }
  1404. if (result === null || result === undefined) break;
  1405. bytesRead++;
  1406. buffer[offset+i] = result;
  1407. }
  1408. if (bytesRead) {
  1409. stream.node.timestamp = Date.now();
  1410. }
  1411. return bytesRead;
  1412. },write:function(stream, buffer, offset, length, pos) {
  1413. if (!stream.tty || !stream.tty.ops.put_char) {
  1414. throw new FS.ErrnoError(60);
  1415. }
  1416. try {
  1417. for (var i = 0; i < length; i++) {
  1418. stream.tty.ops.put_char(stream.tty, buffer[offset+i]);
  1419. }
  1420. } catch (e) {
  1421. throw new FS.ErrnoError(29);
  1422. }
  1423. if (length) {
  1424. stream.node.timestamp = Date.now();
  1425. }
  1426. return i;
  1427. }},default_tty_ops:{get_char:function(tty) {
  1428. if (!tty.input.length) {
  1429. var result = null;
  1430. if (ENVIRONMENT_IS_NODE) {
  1431. // we will read data by chunks of BUFSIZE
  1432. var BUFSIZE = 256;
  1433. var buf = Buffer.alloc(BUFSIZE);
  1434. var bytesRead = 0;
  1435. try {
  1436. bytesRead = fs.readSync(process.stdin.fd, buf, 0, BUFSIZE, -1);
  1437. } catch(e) {
  1438. // Cross-platform differences: on Windows, reading EOF throws an exception, but on other OSes,
  1439. // reading EOF returns 0. Uniformize behavior by treating the EOF exception to return 0.
  1440. if (e.toString().includes('EOF')) bytesRead = 0;
  1441. else throw e;
  1442. }
  1443. if (bytesRead > 0) {
  1444. result = buf.slice(0, bytesRead).toString('utf-8');
  1445. } else {
  1446. result = null;
  1447. }
  1448. } else
  1449. if (typeof window != 'undefined' &&
  1450. typeof window.prompt == 'function') {
  1451. // Browser.
  1452. result = window.prompt('Input: '); // returns null on cancel
  1453. if (result !== null) {
  1454. result += '\n';
  1455. }
  1456. } else if (typeof readline == 'function') {
  1457. // Command line.
  1458. result = readline();
  1459. if (result !== null) {
  1460. result += '\n';
  1461. }
  1462. }
  1463. if (!result) {
  1464. return null;
  1465. }
  1466. tty.input = intArrayFromString(result, true);
  1467. }
  1468. return tty.input.shift();
  1469. },put_char:function(tty, val) {
  1470. if (val === null || val === 10) {
  1471. out(UTF8ArrayToString(tty.output, 0));
  1472. tty.output = [];
  1473. } else {
  1474. if (val != 0) tty.output.push(val); // val == 0 would cut text output off in the middle.
  1475. }
  1476. },fsync:function(tty) {
  1477. if (tty.output && tty.output.length > 0) {
  1478. out(UTF8ArrayToString(tty.output, 0));
  1479. tty.output = [];
  1480. }
  1481. }},default_tty1_ops:{put_char:function(tty, val) {
  1482. if (val === null || val === 10) {
  1483. err(UTF8ArrayToString(tty.output, 0));
  1484. tty.output = [];
  1485. } else {
  1486. if (val != 0) tty.output.push(val);
  1487. }
  1488. },fsync:function(tty) {
  1489. if (tty.output && tty.output.length > 0) {
  1490. err(UTF8ArrayToString(tty.output, 0));
  1491. tty.output = [];
  1492. }
  1493. }}};
  1494. function zeroMemory(address, size) {
  1495. HEAPU8.fill(0, address, address + size);
  1496. return address;
  1497. }
  1498. function alignMemory(size, alignment) {
  1499. assert(alignment, "alignment argument is required");
  1500. return Math.ceil(size / alignment) * alignment;
  1501. }
  1502. function mmapAlloc(size) {
  1503. abort('internal error: mmapAlloc called but `emscripten_builtin_memalign` native symbol not exported');
  1504. }
  1505. var MEMFS = {ops_table:null,mount:function(mount) {
  1506. return MEMFS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
  1507. },createNode:function(parent, name, mode, dev) {
  1508. if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
  1509. // no supported
  1510. throw new FS.ErrnoError(63);
  1511. }
  1512. if (!MEMFS.ops_table) {
  1513. MEMFS.ops_table = {
  1514. dir: {
  1515. node: {
  1516. getattr: MEMFS.node_ops.getattr,
  1517. setattr: MEMFS.node_ops.setattr,
  1518. lookup: MEMFS.node_ops.lookup,
  1519. mknod: MEMFS.node_ops.mknod,
  1520. rename: MEMFS.node_ops.rename,
  1521. unlink: MEMFS.node_ops.unlink,
  1522. rmdir: MEMFS.node_ops.rmdir,
  1523. readdir: MEMFS.node_ops.readdir,
  1524. symlink: MEMFS.node_ops.symlink
  1525. },
  1526. stream: {
  1527. llseek: MEMFS.stream_ops.llseek
  1528. }
  1529. },
  1530. file: {
  1531. node: {
  1532. getattr: MEMFS.node_ops.getattr,
  1533. setattr: MEMFS.node_ops.setattr
  1534. },
  1535. stream: {
  1536. llseek: MEMFS.stream_ops.llseek,
  1537. read: MEMFS.stream_ops.read,
  1538. write: MEMFS.stream_ops.write,
  1539. allocate: MEMFS.stream_ops.allocate,
  1540. mmap: MEMFS.stream_ops.mmap,
  1541. msync: MEMFS.stream_ops.msync
  1542. }
  1543. },
  1544. link: {
  1545. node: {
  1546. getattr: MEMFS.node_ops.getattr,
  1547. setattr: MEMFS.node_ops.setattr,
  1548. readlink: MEMFS.node_ops.readlink
  1549. },
  1550. stream: {}
  1551. },
  1552. chrdev: {
  1553. node: {
  1554. getattr: MEMFS.node_ops.getattr,
  1555. setattr: MEMFS.node_ops.setattr
  1556. },
  1557. stream: FS.chrdev_stream_ops
  1558. }
  1559. };
  1560. }
  1561. var node = FS.createNode(parent, name, mode, dev);
  1562. if (FS.isDir(node.mode)) {
  1563. node.node_ops = MEMFS.ops_table.dir.node;
  1564. node.stream_ops = MEMFS.ops_table.dir.stream;
  1565. node.contents = {};
  1566. } else if (FS.isFile(node.mode)) {
  1567. node.node_ops = MEMFS.ops_table.file.node;
  1568. node.stream_ops = MEMFS.ops_table.file.stream;
  1569. node.usedBytes = 0; // The actual number of bytes used in the typed array, as opposed to contents.length which gives the whole capacity.
  1570. // 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
  1571. // for performance, and used by default. However, typed arrays are not resizable like normal JS arrays are, so there is a small disk size
  1572. // penalty involved for appending file writes that continuously grow a file similar to std::vector capacity vs used -scheme.
  1573. node.contents = null;
  1574. } else if (FS.isLink(node.mode)) {
  1575. node.node_ops = MEMFS.ops_table.link.node;
  1576. node.stream_ops = MEMFS.ops_table.link.stream;
  1577. } else if (FS.isChrdev(node.mode)) {
  1578. node.node_ops = MEMFS.ops_table.chrdev.node;
  1579. node.stream_ops = MEMFS.ops_table.chrdev.stream;
  1580. }
  1581. node.timestamp = Date.now();
  1582. // add the new node to the parent
  1583. if (parent) {
  1584. parent.contents[name] = node;
  1585. parent.timestamp = node.timestamp;
  1586. }
  1587. return node;
  1588. },getFileDataAsTypedArray:function(node) {
  1589. if (!node.contents) return new Uint8Array(0);
  1590. if (node.contents.subarray) return node.contents.subarray(0, node.usedBytes); // Make sure to not return excess unused bytes.
  1591. return new Uint8Array(node.contents);
  1592. },expandFileStorage:function(node, newCapacity) {
  1593. var prevCapacity = node.contents ? node.contents.length : 0;
  1594. if (prevCapacity >= newCapacity) return; // No need to expand, the storage was already large enough.
  1595. // Don't expand strictly to the given requested limit if it's only a very small increase, but instead geometrically grow capacity.
  1596. // For small filesizes (<1MB), perform size*2 geometric increase, but for large sizes, do a much more conservative size*1.125 increase to
  1597. // avoid overshooting the allocation cap by a very large margin.
  1598. var CAPACITY_DOUBLING_MAX = 1024 * 1024;
  1599. newCapacity = Math.max(newCapacity, (prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2.0 : 1.125)) >>> 0);
  1600. if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); // At minimum allocate 256b for each file when expanding.
  1601. var oldContents = node.contents;
  1602. node.contents = new Uint8Array(newCapacity); // Allocate new storage.
  1603. if (node.usedBytes > 0) node.contents.set(oldContents.subarray(0, node.usedBytes), 0); // Copy old data over to the new storage.
  1604. },resizeFileStorage:function(node, newSize) {
  1605. if (node.usedBytes == newSize) return;
  1606. if (newSize == 0) {
  1607. node.contents = null; // Fully decommit when requesting a resize to zero.
  1608. node.usedBytes = 0;
  1609. } else {
  1610. var oldContents = node.contents;
  1611. node.contents = new Uint8Array(newSize); // Allocate new storage.
  1612. if (oldContents) {
  1613. node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))); // Copy old data over to the new storage.
  1614. }
  1615. node.usedBytes = newSize;
  1616. }
  1617. },node_ops:{getattr:function(node) {
  1618. var attr = {};
  1619. // device numbers reuse inode numbers.
  1620. attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
  1621. attr.ino = node.id;
  1622. attr.mode = node.mode;
  1623. attr.nlink = 1;
  1624. attr.uid = 0;
  1625. attr.gid = 0;
  1626. attr.rdev = node.rdev;
  1627. if (FS.isDir(node.mode)) {
  1628. attr.size = 4096;
  1629. } else if (FS.isFile(node.mode)) {
  1630. attr.size = node.usedBytes;
  1631. } else if (FS.isLink(node.mode)) {
  1632. attr.size = node.link.length;
  1633. } else {
  1634. attr.size = 0;
  1635. }
  1636. attr.atime = new Date(node.timestamp);
  1637. attr.mtime = new Date(node.timestamp);
  1638. attr.ctime = new Date(node.timestamp);
  1639. // NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize),
  1640. // but this is not required by the standard.
  1641. attr.blksize = 4096;
  1642. attr.blocks = Math.ceil(attr.size / attr.blksize);
  1643. return attr;
  1644. },setattr:function(node, attr) {
  1645. if (attr.mode !== undefined) {
  1646. node.mode = attr.mode;
  1647. }
  1648. if (attr.timestamp !== undefined) {
  1649. node.timestamp = attr.timestamp;
  1650. }
  1651. if (attr.size !== undefined) {
  1652. MEMFS.resizeFileStorage(node, attr.size);
  1653. }
  1654. },lookup:function(parent, name) {
  1655. throw FS.genericErrors[44];
  1656. },mknod:function(parent, name, mode, dev) {
  1657. return MEMFS.createNode(parent, name, mode, dev);
  1658. },rename:function(old_node, new_dir, new_name) {
  1659. // if we're overwriting a directory at new_name, make sure it's empty.
  1660. if (FS.isDir(old_node.mode)) {
  1661. var new_node;
  1662. try {
  1663. new_node = FS.lookupNode(new_dir, new_name);
  1664. } catch (e) {
  1665. }
  1666. if (new_node) {
  1667. for (var i in new_node.contents) {
  1668. throw new FS.ErrnoError(55);
  1669. }
  1670. }
  1671. }
  1672. // do the internal rewiring
  1673. delete old_node.parent.contents[old_node.name];
  1674. old_node.parent.timestamp = Date.now()
  1675. old_node.name = new_name;
  1676. new_dir.contents[new_name] = old_node;
  1677. new_dir.timestamp = old_node.parent.timestamp;
  1678. old_node.parent = new_dir;
  1679. },unlink:function(parent, name) {
  1680. delete parent.contents[name];
  1681. parent.timestamp = Date.now();
  1682. },rmdir:function(parent, name) {
  1683. var node = FS.lookupNode(parent, name);
  1684. for (var i in node.contents) {
  1685. throw new FS.ErrnoError(55);
  1686. }
  1687. delete parent.contents[name];
  1688. parent.timestamp = Date.now();
  1689. },readdir:function(node) {
  1690. var entries = ['.', '..'];
  1691. for (var key in node.contents) {
  1692. if (!node.contents.hasOwnProperty(key)) {
  1693. continue;
  1694. }
  1695. entries.push(key);
  1696. }
  1697. return entries;
  1698. },symlink:function(parent, newname, oldpath) {
  1699. var node = MEMFS.createNode(parent, newname, 511 /* 0777 */ | 40960, 0);
  1700. node.link = oldpath;
  1701. return node;
  1702. },readlink:function(node) {
  1703. if (!FS.isLink(node.mode)) {
  1704. throw new FS.ErrnoError(28);
  1705. }
  1706. return node.link;
  1707. }},stream_ops:{read:function(stream, buffer, offset, length, position) {
  1708. var contents = stream.node.contents;
  1709. if (position >= stream.node.usedBytes) return 0;
  1710. var size = Math.min(stream.node.usedBytes - position, length);
  1711. assert(size >= 0);
  1712. if (size > 8 && contents.subarray) { // non-trivial, and typed array
  1713. buffer.set(contents.subarray(position, position + size), offset);
  1714. } else {
  1715. for (var i = 0; i < size; i++) buffer[offset + i] = contents[position + i];
  1716. }
  1717. return size;
  1718. },write:function(stream, buffer, offset, length, position, canOwn) {
  1719. // The data buffer should be a typed array view
  1720. assert(!(buffer instanceof ArrayBuffer));
  1721. // If the buffer is located in main memory (HEAP), and if
  1722. // memory can grow, we can't hold on to references of the
  1723. // memory buffer, as they may get invalidated. That means we
  1724. // need to do copy its contents.
  1725. if (buffer.buffer === HEAP8.buffer) {
  1726. canOwn = false;
  1727. }
  1728. if (!length) return 0;
  1729. var node = stream.node;
  1730. node.timestamp = Date.now();
  1731. if (buffer.subarray && (!node.contents || node.contents.subarray)) { // This write is from a typed array to a typed array?
  1732. if (canOwn) {
  1733. assert(position === 0, 'canOwn must imply no weird position inside the file');
  1734. node.contents = buffer.subarray(offset, offset + length);
  1735. node.usedBytes = length;
  1736. return length;
  1737. } 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.
  1738. node.contents = buffer.slice(offset, offset + length);
  1739. node.usedBytes = length;
  1740. return length;
  1741. } else if (position + length <= node.usedBytes) { // Writing to an already allocated and used subrange of the file?
  1742. node.contents.set(buffer.subarray(offset, offset + length), position);
  1743. return length;
  1744. }
  1745. }
  1746. // Appending to an existing file and we need to reallocate, or source data did not come as a typed array.
  1747. MEMFS.expandFileStorage(node, position+length);
  1748. if (node.contents.subarray && buffer.subarray) {
  1749. // Use typed array write which is available.
  1750. node.contents.set(buffer.subarray(offset, offset + length), position);
  1751. } else {
  1752. for (var i = 0; i < length; i++) {
  1753. node.contents[position + i] = buffer[offset + i]; // Or fall back to manual write if not.
  1754. }
  1755. }
  1756. node.usedBytes = Math.max(node.usedBytes, position + length);
  1757. return length;
  1758. },llseek:function(stream, offset, whence) {
  1759. var position = offset;
  1760. if (whence === 1) {
  1761. position += stream.position;
  1762. } else if (whence === 2) {
  1763. if (FS.isFile(stream.node.mode)) {
  1764. position += stream.node.usedBytes;
  1765. }
  1766. }
  1767. if (position < 0) {
  1768. throw new FS.ErrnoError(28);
  1769. }
  1770. return position;
  1771. },allocate:function(stream, offset, length) {
  1772. MEMFS.expandFileStorage(stream.node, offset + length);
  1773. stream.node.usedBytes = Math.max(stream.node.usedBytes, offset + length);
  1774. },mmap:function(stream, length, position, prot, flags) {
  1775. if (!FS.isFile(stream.node.mode)) {
  1776. throw new FS.ErrnoError(43);
  1777. }
  1778. var ptr;
  1779. var allocated;
  1780. var contents = stream.node.contents;
  1781. // Only make a new copy when MAP_PRIVATE is specified.
  1782. if (!(flags & 2) && contents.buffer === buffer) {
  1783. // We can't emulate MAP_SHARED when the file is not backed by the buffer
  1784. // we're mapping to (e.g. the HEAP buffer).
  1785. allocated = false;
  1786. ptr = contents.byteOffset;
  1787. } else {
  1788. // Try to avoid unnecessary slices.
  1789. if (position > 0 || position + length < contents.length) {
  1790. if (contents.subarray) {
  1791. contents = contents.subarray(position, position + length);
  1792. } else {
  1793. contents = Array.prototype.slice.call(contents, position, position + length);
  1794. }
  1795. }
  1796. allocated = true;
  1797. ptr = mmapAlloc(length);
  1798. if (!ptr) {
  1799. throw new FS.ErrnoError(48);
  1800. }
  1801. HEAP8.set(contents, ptr);
  1802. }
  1803. return { ptr: ptr, allocated: allocated };
  1804. },msync:function(stream, buffer, offset, length, mmapFlags) {
  1805. MEMFS.stream_ops.write(stream, buffer, 0, length, offset, false);
  1806. // should we check if bytesWritten and length are the same?
  1807. return 0;
  1808. }}};
  1809. /** @param {boolean=} noRunDep */
  1810. function asyncLoad(url, onload, onerror, noRunDep) {
  1811. var dep = !noRunDep ? getUniqueRunDependency('al ' + url) : '';
  1812. readAsync(url, (arrayBuffer) => {
  1813. assert(arrayBuffer, 'Loading data file "' + url + '" failed (no arrayBuffer).');
  1814. onload(new Uint8Array(arrayBuffer));
  1815. if (dep) removeRunDependency(dep);
  1816. }, (event) => {
  1817. if (onerror) {
  1818. onerror();
  1819. } else {
  1820. throw 'Loading data file "' + url + '" failed.';
  1821. }
  1822. });
  1823. if (dep) addRunDependency(dep);
  1824. }
  1825. var ERRNO_MESSAGES = {0:"Success",1:"Arg list too long",2:"Permission denied",3:"Address already in use",4:"Address not available",5:"Address family not supported by protocol family",6:"No more processes",7:"Socket already connected",8:"Bad file number",9:"Trying to read unreadable message",10:"Mount device busy",11:"Operation canceled",12:"No children",13:"Connection aborted",14:"Connection refused",15:"Connection reset by peer",16:"File locking deadlock error",17:"Destination address required",18:"Math arg out of domain of func",19:"Quota exceeded",20:"File exists",21:"Bad address",22:"File too large",23:"Host is unreachable",24:"Identifier removed",25:"Illegal byte sequence",26:"Connection already in progress",27:"Interrupted system call",28:"Invalid argument",29:"I/O error",30:"Socket is already connected",31:"Is a directory",32:"Too many symbolic links",33:"Too many open files",34:"Too many links",35:"Message too long",36:"Multihop attempted",37:"File or path name too long",38:"Network interface is not configured",39:"Connection reset by network",40:"Network is unreachable",41:"Too many open files in system",42:"No buffer space available",43:"No such device",44:"No such file or directory",45:"Exec format error",46:"No record locks available",47:"The link has been severed",48:"Not enough core",49:"No message of desired type",50:"Protocol not available",51:"No space left on device",52:"Function not implemented",53:"Socket is not connected",54:"Not a directory",55:"Directory not empty",56:"State not recoverable",57:"Socket operation on non-socket",59:"Not a typewriter",60:"No such device or address",61:"Value too large for defined data type",62:"Previous owner died",63:"Not super-user",64:"Broken pipe",65:"Protocol error",66:"Unknown protocol",67:"Protocol wrong type for socket",68:"Math result not representable",69:"Read only file system",70:"Illegal seek",71:"No such process",72:"Stale file handle",73:"Connection timed out",74:"Text file busy",75:"Cross-device link",100:"Device not a stream",101:"Bad font file fmt",102:"Invalid slot",103:"Invalid request code",104:"No anode",105:"Block device required",106:"Channel number out of range",107:"Level 3 halted",108:"Level 3 reset",109:"Link number out of range",110:"Protocol driver not attached",111:"No CSI structure available",112:"Level 2 halted",113:"Invalid exchange",114:"Invalid request descriptor",115:"Exchange full",116:"No data (for no delay io)",117:"Timer expired",118:"Out of streams resources",119:"Machine is not on the network",120:"Package not installed",121:"The object is remote",122:"Advertise error",123:"Srmount error",124:"Communication error on send",125:"Cross mount point (not really error)",126:"Given log. name not unique",127:"f.d. invalid for this operation",128:"Remote address changed",129:"Can access a needed shared lib",130:"Accessing a corrupted shared lib",131:".lib section in a.out corrupted",132:"Attempting to link in too many libs",133:"Attempting to exec a shared library",135:"Streams pipe error",136:"Too many users",137:"Socket type not supported",138:"Not supported",139:"Protocol family not supported",140:"Can't send after socket shutdown",141:"Too many references",142:"Host is down",148:"No medium (in tape drive)",156:"Level 2 not synchronized"};
  1826. var ERRNO_CODES = {};
  1827. function withStackSave(f) {
  1828. var stack = stackSave();
  1829. var ret = f();
  1830. stackRestore(stack);
  1831. return ret;
  1832. }
  1833. function demangle(func) {
  1834. warnOnce('warning: build with -sDEMANGLE_SUPPORT to link in libcxxabi demangling');
  1835. return func;
  1836. }
  1837. function demangleAll(text) {
  1838. var regex =
  1839. /\b_Z[\w\d_]+/g;
  1840. return text.replace(regex,
  1841. function(x) {
  1842. var y = demangle(x);
  1843. return x === y ? x : (y + ' [' + x + ']');
  1844. });
  1845. }
  1846. var FS = {root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:null,genericErrors:{},filesystems:null,syncFSRequests:0,lookupPath:(path, opts = {}) => {
  1847. path = PATH_FS.resolve(path);
  1848. if (!path) return { path: '', node: null };
  1849. var defaults = {
  1850. follow_mount: true,
  1851. recurse_count: 0
  1852. };
  1853. opts = Object.assign(defaults, opts)
  1854. if (opts.recurse_count > 8) { // max recursive lookup of 8
  1855. throw new FS.ErrnoError(32);
  1856. }
  1857. // split the absolute path
  1858. var parts = path.split('/').filter((p) => !!p);
  1859. // start at the root
  1860. var current = FS.root;
  1861. var current_path = '/';
  1862. for (var i = 0; i < parts.length; i++) {
  1863. var islast = (i === parts.length-1);
  1864. if (islast && opts.parent) {
  1865. // stop resolving
  1866. break;
  1867. }
  1868. current = FS.lookupNode(current, parts[i]);
  1869. current_path = PATH.join2(current_path, parts[i]);
  1870. // jump to the mount's root node if this is a mountpoint
  1871. if (FS.isMountpoint(current)) {
  1872. if (!islast || (islast && opts.follow_mount)) {
  1873. current = current.mounted.root;
  1874. }
  1875. }
  1876. // by default, lookupPath will not follow a symlink if it is the final path component.
  1877. // setting opts.follow = true will override this behavior.
  1878. if (!islast || opts.follow) {
  1879. var count = 0;
  1880. while (FS.isLink(current.mode)) {
  1881. var link = FS.readlink(current_path);
  1882. current_path = PATH_FS.resolve(PATH.dirname(current_path), link);
  1883. var lookup = FS.lookupPath(current_path, { recurse_count: opts.recurse_count + 1 });
  1884. current = lookup.node;
  1885. if (count++ > 40) { // limit max consecutive symlinks to 40 (SYMLOOP_MAX).
  1886. throw new FS.ErrnoError(32);
  1887. }
  1888. }
  1889. }
  1890. }
  1891. return { path: current_path, node: current };
  1892. },getPath:(node) => {
  1893. var path;
  1894. while (true) {
  1895. if (FS.isRoot(node)) {
  1896. var mount = node.mount.mountpoint;
  1897. if (!path) return mount;
  1898. return mount[mount.length-1] !== '/' ? mount + '/' + path : mount + path;
  1899. }
  1900. path = path ? node.name + '/' + path : node.name;
  1901. node = node.parent;
  1902. }
  1903. },hashName:(parentid, name) => {
  1904. var hash = 0;
  1905. for (var i = 0; i < name.length; i++) {
  1906. hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
  1907. }
  1908. return ((parentid + hash) >>> 0) % FS.nameTable.length;
  1909. },hashAddNode:(node) => {
  1910. var hash = FS.hashName(node.parent.id, node.name);
  1911. node.name_next = FS.nameTable[hash];
  1912. FS.nameTable[hash] = node;
  1913. },hashRemoveNode:(node) => {
  1914. var hash = FS.hashName(node.parent.id, node.name);
  1915. if (FS.nameTable[hash] === node) {
  1916. FS.nameTable[hash] = node.name_next;
  1917. } else {
  1918. var current = FS.nameTable[hash];
  1919. while (current) {
  1920. if (current.name_next === node) {
  1921. current.name_next = node.name_next;
  1922. break;
  1923. }
  1924. current = current.name_next;
  1925. }
  1926. }
  1927. },lookupNode:(parent, name) => {
  1928. var errCode = FS.mayLookup(parent);
  1929. if (errCode) {
  1930. throw new FS.ErrnoError(errCode, parent);
  1931. }
  1932. var hash = FS.hashName(parent.id, name);
  1933. for (var node = FS.nameTable[hash]; node; node = node.name_next) {
  1934. var nodeName = node.name;
  1935. if (node.parent.id === parent.id && nodeName === name) {
  1936. return node;
  1937. }
  1938. }
  1939. // if we failed to find it in the cache, call into the VFS
  1940. return FS.lookup(parent, name);
  1941. },createNode:(parent, name, mode, rdev) => {
  1942. assert(typeof parent == 'object')
  1943. var node = new FS.FSNode(parent, name, mode, rdev);
  1944. FS.hashAddNode(node);
  1945. return node;
  1946. },destroyNode:(node) => {
  1947. FS.hashRemoveNode(node);
  1948. },isRoot:(node) => {
  1949. return node === node.parent;
  1950. },isMountpoint:(node) => {
  1951. return !!node.mounted;
  1952. },isFile:(mode) => {
  1953. return (mode & 61440) === 32768;
  1954. },isDir:(mode) => {
  1955. return (mode & 61440) === 16384;
  1956. },isLink:(mode) => {
  1957. return (mode & 61440) === 40960;
  1958. },isChrdev:(mode) => {
  1959. return (mode & 61440) === 8192;
  1960. },isBlkdev:(mode) => {
  1961. return (mode & 61440) === 24576;
  1962. },isFIFO:(mode) => {
  1963. return (mode & 61440) === 4096;
  1964. },isSocket:(mode) => {
  1965. return (mode & 49152) === 49152;
  1966. },flagModes:{"r":0,"r+":2,"w":577,"w+":578,"a":1089,"a+":1090},modeStringToFlags:(str) => {
  1967. var flags = FS.flagModes[str];
  1968. if (typeof flags == 'undefined') {
  1969. throw new Error('Unknown file open mode: ' + str);
  1970. }
  1971. return flags;
  1972. },flagsToPermissionString:(flag) => {
  1973. var perms = ['r', 'w', 'rw'][flag & 3];
  1974. if ((flag & 512)) {
  1975. perms += 'w';
  1976. }
  1977. return perms;
  1978. },nodePermissions:(node, perms) => {
  1979. if (FS.ignorePermissions) {
  1980. return 0;
  1981. }
  1982. // return 0 if any user, group or owner bits are set.
  1983. if (perms.includes('r') && !(node.mode & 292)) {
  1984. return 2;
  1985. } else if (perms.includes('w') && !(node.mode & 146)) {
  1986. return 2;
  1987. } else if (perms.includes('x') && !(node.mode & 73)) {
  1988. return 2;
  1989. }
  1990. return 0;
  1991. },mayLookup:(dir) => {
  1992. var errCode = FS.nodePermissions(dir, 'x');
  1993. if (errCode) return errCode;
  1994. if (!dir.node_ops.lookup) return 2;
  1995. return 0;
  1996. },mayCreate:(dir, name) => {
  1997. try {
  1998. var node = FS.lookupNode(dir, name);
  1999. return 20;
  2000. } catch (e) {
  2001. }
  2002. return FS.nodePermissions(dir, 'wx');
  2003. },mayDelete:(dir, name, isdir) => {
  2004. var node;
  2005. try {
  2006. node = FS.lookupNode(dir, name);
  2007. } catch (e) {
  2008. return e.errno;
  2009. }
  2010. var errCode = FS.nodePermissions(dir, 'wx');
  2011. if (errCode) {
  2012. return errCode;
  2013. }
  2014. if (isdir) {
  2015. if (!FS.isDir(node.mode)) {
  2016. return 54;
  2017. }
  2018. if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
  2019. return 10;
  2020. }
  2021. } else {
  2022. if (FS.isDir(node.mode)) {
  2023. return 31;
  2024. }
  2025. }
  2026. return 0;
  2027. },mayOpen:(node, flags) => {
  2028. if (!node) {
  2029. return 44;
  2030. }
  2031. if (FS.isLink(node.mode)) {
  2032. return 32;
  2033. } else if (FS.isDir(node.mode)) {
  2034. if (FS.flagsToPermissionString(flags) !== 'r' || // opening for write
  2035. (flags & 512)) { // TODO: check for O_SEARCH? (== search for dir only)
  2036. return 31;
  2037. }
  2038. }
  2039. return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
  2040. },MAX_OPEN_FDS:4096,nextfd:(fd_start = 0, fd_end = FS.MAX_OPEN_FDS) => {
  2041. for (var fd = fd_start; fd <= fd_end; fd++) {
  2042. if (!FS.streams[fd]) {
  2043. return fd;
  2044. }
  2045. }
  2046. throw new FS.ErrnoError(33);
  2047. },getStream:(fd) => FS.streams[fd],createStream:(stream, fd_start, fd_end) => {
  2048. if (!FS.FSStream) {
  2049. FS.FSStream = /** @constructor */ function() {
  2050. this.shared = { };
  2051. };
  2052. FS.FSStream.prototype = {};
  2053. Object.defineProperties(FS.FSStream.prototype, {
  2054. object: {
  2055. /** @this {FS.FSStream} */
  2056. get: function() { return this.node; },
  2057. /** @this {FS.FSStream} */
  2058. set: function(val) { this.node = val; }
  2059. },
  2060. isRead: {
  2061. /** @this {FS.FSStream} */
  2062. get: function() { return (this.flags & 2097155) !== 1; }
  2063. },
  2064. isWrite: {
  2065. /** @this {FS.FSStream} */
  2066. get: function() { return (this.flags & 2097155) !== 0; }
  2067. },
  2068. isAppend: {
  2069. /** @this {FS.FSStream} */
  2070. get: function() { return (this.flags & 1024); }
  2071. },
  2072. flags: {
  2073. /** @this {FS.FSStream} */
  2074. get: function() { return this.shared.flags; },
  2075. /** @this {FS.FSStream} */
  2076. set: function(val) { this.shared.flags = val; },
  2077. },
  2078. position : {
  2079. /** @this {FS.FSStream} */
  2080. get: function() { return this.shared.position; },
  2081. /** @this {FS.FSStream} */
  2082. set: function(val) { this.shared.position = val; },
  2083. },
  2084. });
  2085. }
  2086. // clone it, so we can return an instance of FSStream
  2087. stream = Object.assign(new FS.FSStream(), stream);
  2088. var fd = FS.nextfd(fd_start, fd_end);
  2089. stream.fd = fd;
  2090. FS.streams[fd] = stream;
  2091. return stream;
  2092. },closeStream:(fd) => {
  2093. FS.streams[fd] = null;
  2094. },chrdev_stream_ops:{open:(stream) => {
  2095. var device = FS.getDevice(stream.node.rdev);
  2096. // override node's stream ops with the device's
  2097. stream.stream_ops = device.stream_ops;
  2098. // forward the open call
  2099. if (stream.stream_ops.open) {
  2100. stream.stream_ops.open(stream);
  2101. }
  2102. },llseek:() => {
  2103. throw new FS.ErrnoError(70);
  2104. }},major:(dev) => ((dev) >> 8),minor:(dev) => ((dev) & 0xff),makedev:(ma, mi) => ((ma) << 8 | (mi)),registerDevice:(dev, ops) => {
  2105. FS.devices[dev] = { stream_ops: ops };
  2106. },getDevice:(dev) => FS.devices[dev],getMounts:(mount) => {
  2107. var mounts = [];
  2108. var check = [mount];
  2109. while (check.length) {
  2110. var m = check.pop();
  2111. mounts.push(m);
  2112. check.push.apply(check, m.mounts);
  2113. }
  2114. return mounts;
  2115. },syncfs:(populate, callback) => {
  2116. if (typeof populate == 'function') {
  2117. callback = populate;
  2118. populate = false;
  2119. }
  2120. FS.syncFSRequests++;
  2121. if (FS.syncFSRequests > 1) {
  2122. err('warning: ' + FS.syncFSRequests + ' FS.syncfs operations in flight at once, probably just doing extra work');
  2123. }
  2124. var mounts = FS.getMounts(FS.root.mount);
  2125. var completed = 0;
  2126. function doCallback(errCode) {
  2127. assert(FS.syncFSRequests > 0);
  2128. FS.syncFSRequests--;
  2129. return callback(errCode);
  2130. }
  2131. function done(errCode) {
  2132. if (errCode) {
  2133. if (!done.errored) {
  2134. done.errored = true;
  2135. return doCallback(errCode);
  2136. }
  2137. return;
  2138. }
  2139. if (++completed >= mounts.length) {
  2140. doCallback(null);
  2141. }
  2142. };
  2143. // sync all mounts
  2144. mounts.forEach((mount) => {
  2145. if (!mount.type.syncfs) {
  2146. return done(null);
  2147. }
  2148. mount.type.syncfs(mount, populate, done);
  2149. });
  2150. },mount:(type, opts, mountpoint) => {
  2151. if (typeof type == 'string') {
  2152. // The filesystem was not included, and instead we have an error
  2153. // message stored in the variable.
  2154. throw type;
  2155. }
  2156. var root = mountpoint === '/';
  2157. var pseudo = !mountpoint;
  2158. var node;
  2159. if (root && FS.root) {
  2160. throw new FS.ErrnoError(10);
  2161. } else if (!root && !pseudo) {
  2162. var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
  2163. mountpoint = lookup.path; // use the absolute path
  2164. node = lookup.node;
  2165. if (FS.isMountpoint(node)) {
  2166. throw new FS.ErrnoError(10);
  2167. }
  2168. if (!FS.isDir(node.mode)) {
  2169. throw new FS.ErrnoError(54);
  2170. }
  2171. }
  2172. var mount = {
  2173. type: type,
  2174. opts: opts,
  2175. mountpoint: mountpoint,
  2176. mounts: []
  2177. };
  2178. // create a root node for the fs
  2179. var mountRoot = type.mount(mount);
  2180. mountRoot.mount = mount;
  2181. mount.root = mountRoot;
  2182. if (root) {
  2183. FS.root = mountRoot;
  2184. } else if (node) {
  2185. // set as a mountpoint
  2186. node.mounted = mount;
  2187. // add the new mount to the current mount's children
  2188. if (node.mount) {
  2189. node.mount.mounts.push(mount);
  2190. }
  2191. }
  2192. return mountRoot;
  2193. },unmount:(mountpoint) => {
  2194. var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
  2195. if (!FS.isMountpoint(lookup.node)) {
  2196. throw new FS.ErrnoError(28);
  2197. }
  2198. // destroy the nodes for this mount, and all its child mounts
  2199. var node = lookup.node;
  2200. var mount = node.mounted;
  2201. var mounts = FS.getMounts(mount);
  2202. Object.keys(FS.nameTable).forEach((hash) => {
  2203. var current = FS.nameTable[hash];
  2204. while (current) {
  2205. var next = current.name_next;
  2206. if (mounts.includes(current.mount)) {
  2207. FS.destroyNode(current);
  2208. }
  2209. current = next;
  2210. }
  2211. });
  2212. // no longer a mountpoint
  2213. node.mounted = null;
  2214. // remove this mount from the child mounts
  2215. var idx = node.mount.mounts.indexOf(mount);
  2216. assert(idx !== -1);
  2217. node.mount.mounts.splice(idx, 1);
  2218. },lookup:(parent, name) => {
  2219. return parent.node_ops.lookup(parent, name);
  2220. },mknod:(path, mode, dev) => {
  2221. var lookup = FS.lookupPath(path, { parent: true });
  2222. var parent = lookup.node;
  2223. var name = PATH.basename(path);
  2224. if (!name || name === '.' || name === '..') {
  2225. throw new FS.ErrnoError(28);
  2226. }
  2227. var errCode = FS.mayCreate(parent, name);
  2228. if (errCode) {
  2229. throw new FS.ErrnoError(errCode);
  2230. }
  2231. if (!parent.node_ops.mknod) {
  2232. throw new FS.ErrnoError(63);
  2233. }
  2234. return parent.node_ops.mknod(parent, name, mode, dev);
  2235. },create:(path, mode) => {
  2236. mode = mode !== undefined ? mode : 438 /* 0666 */;
  2237. mode &= 4095;
  2238. mode |= 32768;
  2239. return FS.mknod(path, mode, 0);
  2240. },mkdir:(path, mode) => {
  2241. mode = mode !== undefined ? mode : 511 /* 0777 */;
  2242. mode &= 511 | 512;
  2243. mode |= 16384;
  2244. return FS.mknod(path, mode, 0);
  2245. },mkdirTree:(path, mode) => {
  2246. var dirs = path.split('/');
  2247. var d = '';
  2248. for (var i = 0; i < dirs.length; ++i) {
  2249. if (!dirs[i]) continue;
  2250. d += '/' + dirs[i];
  2251. try {
  2252. FS.mkdir(d, mode);
  2253. } catch(e) {
  2254. if (e.errno != 20) throw e;
  2255. }
  2256. }
  2257. },mkdev:(path, mode, dev) => {
  2258. if (typeof dev == 'undefined') {
  2259. dev = mode;
  2260. mode = 438 /* 0666 */;
  2261. }
  2262. mode |= 8192;
  2263. return FS.mknod(path, mode, dev);
  2264. },symlink:(oldpath, newpath) => {
  2265. if (!PATH_FS.resolve(oldpath)) {
  2266. throw new FS.ErrnoError(44);
  2267. }
  2268. var lookup = FS.lookupPath(newpath, { parent: true });
  2269. var parent = lookup.node;
  2270. if (!parent) {
  2271. throw new FS.ErrnoError(44);
  2272. }
  2273. var newname = PATH.basename(newpath);
  2274. var errCode = FS.mayCreate(parent, newname);
  2275. if (errCode) {
  2276. throw new FS.ErrnoError(errCode);
  2277. }
  2278. if (!parent.node_ops.symlink) {
  2279. throw new FS.ErrnoError(63);
  2280. }
  2281. return parent.node_ops.symlink(parent, newname, oldpath);
  2282. },rename:(old_path, new_path) => {
  2283. var old_dirname = PATH.dirname(old_path);
  2284. var new_dirname = PATH.dirname(new_path);
  2285. var old_name = PATH.basename(old_path);
  2286. var new_name = PATH.basename(new_path);
  2287. // parents must exist
  2288. var lookup, old_dir, new_dir;
  2289. // let the errors from non existant directories percolate up
  2290. lookup = FS.lookupPath(old_path, { parent: true });
  2291. old_dir = lookup.node;
  2292. lookup = FS.lookupPath(new_path, { parent: true });
  2293. new_dir = lookup.node;
  2294. if (!old_dir || !new_dir) throw new FS.ErrnoError(44);
  2295. // need to be part of the same mount
  2296. if (old_dir.mount !== new_dir.mount) {
  2297. throw new FS.ErrnoError(75);
  2298. }
  2299. // source must exist
  2300. var old_node = FS.lookupNode(old_dir, old_name);
  2301. // old path should not be an ancestor of the new path
  2302. var relative = PATH_FS.relative(old_path, new_dirname);
  2303. if (relative.charAt(0) !== '.') {
  2304. throw new FS.ErrnoError(28);
  2305. }
  2306. // new path should not be an ancestor of the old path
  2307. relative = PATH_FS.relative(new_path, old_dirname);
  2308. if (relative.charAt(0) !== '.') {
  2309. throw new FS.ErrnoError(55);
  2310. }
  2311. // see if the new path already exists
  2312. var new_node;
  2313. try {
  2314. new_node = FS.lookupNode(new_dir, new_name);
  2315. } catch (e) {
  2316. // not fatal
  2317. }
  2318. // early out if nothing needs to change
  2319. if (old_node === new_node) {
  2320. return;
  2321. }
  2322. // we'll need to delete the old entry
  2323. var isdir = FS.isDir(old_node.mode);
  2324. var errCode = FS.mayDelete(old_dir, old_name, isdir);
  2325. if (errCode) {
  2326. throw new FS.ErrnoError(errCode);
  2327. }
  2328. // need delete permissions if we'll be overwriting.
  2329. // need create permissions if new doesn't already exist.
  2330. errCode = new_node ?
  2331. FS.mayDelete(new_dir, new_name, isdir) :
  2332. FS.mayCreate(new_dir, new_name);
  2333. if (errCode) {
  2334. throw new FS.ErrnoError(errCode);
  2335. }
  2336. if (!old_dir.node_ops.rename) {
  2337. throw new FS.ErrnoError(63);
  2338. }
  2339. if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) {
  2340. throw new FS.ErrnoError(10);
  2341. }
  2342. // if we are going to change the parent, check write permissions
  2343. if (new_dir !== old_dir) {
  2344. errCode = FS.nodePermissions(old_dir, 'w');
  2345. if (errCode) {
  2346. throw new FS.ErrnoError(errCode);
  2347. }
  2348. }
  2349. // remove the node from the lookup hash
  2350. FS.hashRemoveNode(old_node);
  2351. // do the underlying fs rename
  2352. try {
  2353. old_dir.node_ops.rename(old_node, new_dir, new_name);
  2354. } catch (e) {
  2355. throw e;
  2356. } finally {
  2357. // add the node back to the hash (in case node_ops.rename
  2358. // changed its name)
  2359. FS.hashAddNode(old_node);
  2360. }
  2361. },rmdir:(path) => {
  2362. var lookup = FS.lookupPath(path, { parent: true });
  2363. var parent = lookup.node;
  2364. var name = PATH.basename(path);
  2365. var node = FS.lookupNode(parent, name);
  2366. var errCode = FS.mayDelete(parent, name, true);
  2367. if (errCode) {
  2368. throw new FS.ErrnoError(errCode);
  2369. }
  2370. if (!parent.node_ops.rmdir) {
  2371. throw new FS.ErrnoError(63);
  2372. }
  2373. if (FS.isMountpoint(node)) {
  2374. throw new FS.ErrnoError(10);
  2375. }
  2376. parent.node_ops.rmdir(parent, name);
  2377. FS.destroyNode(node);
  2378. },readdir:(path) => {
  2379. var lookup = FS.lookupPath(path, { follow: true });
  2380. var node = lookup.node;
  2381. if (!node.node_ops.readdir) {
  2382. throw new FS.ErrnoError(54);
  2383. }
  2384. return node.node_ops.readdir(node);
  2385. },unlink:(path) => {
  2386. var lookup = FS.lookupPath(path, { parent: true });
  2387. var parent = lookup.node;
  2388. if (!parent) {
  2389. throw new FS.ErrnoError(44);
  2390. }
  2391. var name = PATH.basename(path);
  2392. var node = FS.lookupNode(parent, name);
  2393. var errCode = FS.mayDelete(parent, name, false);
  2394. if (errCode) {
  2395. // According to POSIX, we should map EISDIR to EPERM, but
  2396. // we instead do what Linux does (and we must, as we use
  2397. // the musl linux libc).
  2398. throw new FS.ErrnoError(errCode);
  2399. }
  2400. if (!parent.node_ops.unlink) {
  2401. throw new FS.ErrnoError(63);
  2402. }
  2403. if (FS.isMountpoint(node)) {
  2404. throw new FS.ErrnoError(10);
  2405. }
  2406. parent.node_ops.unlink(parent, name);
  2407. FS.destroyNode(node);
  2408. },readlink:(path) => {
  2409. var lookup = FS.lookupPath(path);
  2410. var link = lookup.node;
  2411. if (!link) {
  2412. throw new FS.ErrnoError(44);
  2413. }
  2414. if (!link.node_ops.readlink) {
  2415. throw new FS.ErrnoError(28);
  2416. }
  2417. return PATH_FS.resolve(FS.getPath(link.parent), link.node_ops.readlink(link));
  2418. },stat:(path, dontFollow) => {
  2419. var lookup = FS.lookupPath(path, { follow: !dontFollow });
  2420. var node = lookup.node;
  2421. if (!node) {
  2422. throw new FS.ErrnoError(44);
  2423. }
  2424. if (!node.node_ops.getattr) {
  2425. throw new FS.ErrnoError(63);
  2426. }
  2427. return node.node_ops.getattr(node);
  2428. },lstat:(path) => {
  2429. return FS.stat(path, true);
  2430. },chmod:(path, mode, dontFollow) => {
  2431. var node;
  2432. if (typeof path == 'string') {
  2433. var lookup = FS.lookupPath(path, { follow: !dontFollow });
  2434. node = lookup.node;
  2435. } else {
  2436. node = path;
  2437. }
  2438. if (!node.node_ops.setattr) {
  2439. throw new FS.ErrnoError(63);
  2440. }
  2441. node.node_ops.setattr(node, {
  2442. mode: (mode & 4095) | (node.mode & ~4095),
  2443. timestamp: Date.now()
  2444. });
  2445. },lchmod:(path, mode) => {
  2446. FS.chmod(path, mode, true);
  2447. },fchmod:(fd, mode) => {
  2448. var stream = FS.getStream(fd);
  2449. if (!stream) {
  2450. throw new FS.ErrnoError(8);
  2451. }
  2452. FS.chmod(stream.node, mode);
  2453. },chown:(path, uid, gid, dontFollow) => {
  2454. var node;
  2455. if (typeof path == 'string') {
  2456. var lookup = FS.lookupPath(path, { follow: !dontFollow });
  2457. node = lookup.node;
  2458. } else {
  2459. node = path;
  2460. }
  2461. if (!node.node_ops.setattr) {
  2462. throw new FS.ErrnoError(63);
  2463. }
  2464. node.node_ops.setattr(node, {
  2465. timestamp: Date.now()
  2466. // we ignore the uid / gid for now
  2467. });
  2468. },lchown:(path, uid, gid) => {
  2469. FS.chown(path, uid, gid, true);
  2470. },fchown:(fd, uid, gid) => {
  2471. var stream = FS.getStream(fd);
  2472. if (!stream) {
  2473. throw new FS.ErrnoError(8);
  2474. }
  2475. FS.chown(stream.node, uid, gid);
  2476. },truncate:(path, len) => {
  2477. if (len < 0) {
  2478. throw new FS.ErrnoError(28);
  2479. }
  2480. var node;
  2481. if (typeof path == 'string') {
  2482. var lookup = FS.lookupPath(path, { follow: true });
  2483. node = lookup.node;
  2484. } else {
  2485. node = path;
  2486. }
  2487. if (!node.node_ops.setattr) {
  2488. throw new FS.ErrnoError(63);
  2489. }
  2490. if (FS.isDir(node.mode)) {
  2491. throw new FS.ErrnoError(31);
  2492. }
  2493. if (!FS.isFile(node.mode)) {
  2494. throw new FS.ErrnoError(28);
  2495. }
  2496. var errCode = FS.nodePermissions(node, 'w');
  2497. if (errCode) {
  2498. throw new FS.ErrnoError(errCode);
  2499. }
  2500. node.node_ops.setattr(node, {
  2501. size: len,
  2502. timestamp: Date.now()
  2503. });
  2504. },ftruncate:(fd, len) => {
  2505. var stream = FS.getStream(fd);
  2506. if (!stream) {
  2507. throw new FS.ErrnoError(8);
  2508. }
  2509. if ((stream.flags & 2097155) === 0) {
  2510. throw new FS.ErrnoError(28);
  2511. }
  2512. FS.truncate(stream.node, len);
  2513. },utime:(path, atime, mtime) => {
  2514. var lookup = FS.lookupPath(path, { follow: true });
  2515. var node = lookup.node;
  2516. node.node_ops.setattr(node, {
  2517. timestamp: Math.max(atime, mtime)
  2518. });
  2519. },open:(path, flags, mode) => {
  2520. if (path === "") {
  2521. throw new FS.ErrnoError(44);
  2522. }
  2523. flags = typeof flags == 'string' ? FS.modeStringToFlags(flags) : flags;
  2524. mode = typeof mode == 'undefined' ? 438 /* 0666 */ : mode;
  2525. if ((flags & 64)) {
  2526. mode = (mode & 4095) | 32768;
  2527. } else {
  2528. mode = 0;
  2529. }
  2530. var node;
  2531. if (typeof path == 'object') {
  2532. node = path;
  2533. } else {
  2534. path = PATH.normalize(path);
  2535. try {
  2536. var lookup = FS.lookupPath(path, {
  2537. follow: !(flags & 131072)
  2538. });
  2539. node = lookup.node;
  2540. } catch (e) {
  2541. // ignore
  2542. }
  2543. }
  2544. // perhaps we need to create the node
  2545. var created = false;
  2546. if ((flags & 64)) {
  2547. if (node) {
  2548. // if O_CREAT and O_EXCL are set, error out if the node already exists
  2549. if ((flags & 128)) {
  2550. throw new FS.ErrnoError(20);
  2551. }
  2552. } else {
  2553. // node doesn't exist, try to create it
  2554. node = FS.mknod(path, mode, 0);
  2555. created = true;
  2556. }
  2557. }
  2558. if (!node) {
  2559. throw new FS.ErrnoError(44);
  2560. }
  2561. // can't truncate a device
  2562. if (FS.isChrdev(node.mode)) {
  2563. flags &= ~512;
  2564. }
  2565. // if asked only for a directory, then this must be one
  2566. if ((flags & 65536) && !FS.isDir(node.mode)) {
  2567. throw new FS.ErrnoError(54);
  2568. }
  2569. // check permissions, if this is not a file we just created now (it is ok to
  2570. // create and write to a file with read-only permissions; it is read-only
  2571. // for later use)
  2572. if (!created) {
  2573. var errCode = FS.mayOpen(node, flags);
  2574. if (errCode) {
  2575. throw new FS.ErrnoError(errCode);
  2576. }
  2577. }
  2578. // do truncation if necessary
  2579. if ((flags & 512) && !created) {
  2580. FS.truncate(node, 0);
  2581. }
  2582. // we've already handled these, don't pass down to the underlying vfs
  2583. flags &= ~(128 | 512 | 131072);
  2584. // register the stream with the filesystem
  2585. var stream = FS.createStream({
  2586. node: node,
  2587. path: FS.getPath(node), // we want the absolute path to the node
  2588. flags: flags,
  2589. seekable: true,
  2590. position: 0,
  2591. stream_ops: node.stream_ops,
  2592. // used by the file family libc calls (fopen, fwrite, ferror, etc.)
  2593. ungotten: [],
  2594. error: false
  2595. });
  2596. // call the new stream's open function
  2597. if (stream.stream_ops.open) {
  2598. stream.stream_ops.open(stream);
  2599. }
  2600. if (Module['logReadFiles'] && !(flags & 1)) {
  2601. if (!FS.readFiles) FS.readFiles = {};
  2602. if (!(path in FS.readFiles)) {
  2603. FS.readFiles[path] = 1;
  2604. }
  2605. }
  2606. return stream;
  2607. },close:(stream) => {
  2608. if (FS.isClosed(stream)) {
  2609. throw new FS.ErrnoError(8);
  2610. }
  2611. if (stream.getdents) stream.getdents = null; // free readdir state
  2612. try {
  2613. if (stream.stream_ops.close) {
  2614. stream.stream_ops.close(stream);
  2615. }
  2616. } catch (e) {
  2617. throw e;
  2618. } finally {
  2619. FS.closeStream(stream.fd);
  2620. }
  2621. stream.fd = null;
  2622. },isClosed:(stream) => {
  2623. return stream.fd === null;
  2624. },llseek:(stream, offset, whence) => {
  2625. if (FS.isClosed(stream)) {
  2626. throw new FS.ErrnoError(8);
  2627. }
  2628. if (!stream.seekable || !stream.stream_ops.llseek) {
  2629. throw new FS.ErrnoError(70);
  2630. }
  2631. if (whence != 0 && whence != 1 && whence != 2) {
  2632. throw new FS.ErrnoError(28);
  2633. }
  2634. stream.position = stream.stream_ops.llseek(stream, offset, whence);
  2635. stream.ungotten = [];
  2636. return stream.position;
  2637. },read:(stream, buffer, offset, length, position) => {
  2638. if (length < 0 || position < 0) {
  2639. throw new FS.ErrnoError(28);
  2640. }
  2641. if (FS.isClosed(stream)) {
  2642. throw new FS.ErrnoError(8);
  2643. }
  2644. if ((stream.flags & 2097155) === 1) {
  2645. throw new FS.ErrnoError(8);
  2646. }
  2647. if (FS.isDir(stream.node.mode)) {
  2648. throw new FS.ErrnoError(31);
  2649. }
  2650. if (!stream.stream_ops.read) {
  2651. throw new FS.ErrnoError(28);
  2652. }
  2653. var seeking = typeof position != 'undefined';
  2654. if (!seeking) {
  2655. position = stream.position;
  2656. } else if (!stream.seekable) {
  2657. throw new FS.ErrnoError(70);
  2658. }
  2659. var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position);
  2660. if (!seeking) stream.position += bytesRead;
  2661. return bytesRead;
  2662. },write:(stream, buffer, offset, length, position, canOwn) => {
  2663. if (length < 0 || position < 0) {
  2664. throw new FS.ErrnoError(28);
  2665. }
  2666. if (FS.isClosed(stream)) {
  2667. throw new FS.ErrnoError(8);
  2668. }
  2669. if ((stream.flags & 2097155) === 0) {
  2670. throw new FS.ErrnoError(8);
  2671. }
  2672. if (FS.isDir(stream.node.mode)) {
  2673. throw new FS.ErrnoError(31);
  2674. }
  2675. if (!stream.stream_ops.write) {
  2676. throw new FS.ErrnoError(28);
  2677. }
  2678. if (stream.seekable && stream.flags & 1024) {
  2679. // seek to the end before writing in append mode
  2680. FS.llseek(stream, 0, 2);
  2681. }
  2682. var seeking = typeof position != 'undefined';
  2683. if (!seeking) {
  2684. position = stream.position;
  2685. } else if (!stream.seekable) {
  2686. throw new FS.ErrnoError(70);
  2687. }
  2688. var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
  2689. if (!seeking) stream.position += bytesWritten;
  2690. return bytesWritten;
  2691. },allocate:(stream, offset, length) => {
  2692. if (FS.isClosed(stream)) {
  2693. throw new FS.ErrnoError(8);
  2694. }
  2695. if (offset < 0 || length <= 0) {
  2696. throw new FS.ErrnoError(28);
  2697. }
  2698. if ((stream.flags & 2097155) === 0) {
  2699. throw new FS.ErrnoError(8);
  2700. }
  2701. if (!FS.isFile(stream.node.mode) && !FS.isDir(stream.node.mode)) {
  2702. throw new FS.ErrnoError(43);
  2703. }
  2704. if (!stream.stream_ops.allocate) {
  2705. throw new FS.ErrnoError(138);
  2706. }
  2707. stream.stream_ops.allocate(stream, offset, length);
  2708. },mmap:(stream, length, position, prot, flags) => {
  2709. // User requests writing to file (prot & PROT_WRITE != 0).
  2710. // Checking if we have permissions to write to the file unless
  2711. // MAP_PRIVATE flag is set. According to POSIX spec it is possible
  2712. // to write to file opened in read-only mode with MAP_PRIVATE flag,
  2713. // as all modifications will be visible only in the memory of
  2714. // the current process.
  2715. if ((prot & 2) !== 0
  2716. && (flags & 2) === 0
  2717. && (stream.flags & 2097155) !== 2) {
  2718. throw new FS.ErrnoError(2);
  2719. }
  2720. if ((stream.flags & 2097155) === 1) {
  2721. throw new FS.ErrnoError(2);
  2722. }
  2723. if (!stream.stream_ops.mmap) {
  2724. throw new FS.ErrnoError(43);
  2725. }
  2726. return stream.stream_ops.mmap(stream, length, position, prot, flags);
  2727. },msync:(stream, buffer, offset, length, mmapFlags) => {
  2728. if (!stream.stream_ops.msync) {
  2729. return 0;
  2730. }
  2731. return stream.stream_ops.msync(stream, buffer, offset, length, mmapFlags);
  2732. },munmap:(stream) => 0,ioctl:(stream, cmd, arg) => {
  2733. if (!stream.stream_ops.ioctl) {
  2734. throw new FS.ErrnoError(59);
  2735. }
  2736. return stream.stream_ops.ioctl(stream, cmd, arg);
  2737. },readFile:(path, opts = {}) => {
  2738. opts.flags = opts.flags || 0;
  2739. opts.encoding = opts.encoding || 'binary';
  2740. if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
  2741. throw new Error('Invalid encoding type "' + opts.encoding + '"');
  2742. }
  2743. var ret;
  2744. var stream = FS.open(path, opts.flags);
  2745. var stat = FS.stat(path);
  2746. var length = stat.size;
  2747. var buf = new Uint8Array(length);
  2748. FS.read(stream, buf, 0, length, 0);
  2749. if (opts.encoding === 'utf8') {
  2750. ret = UTF8ArrayToString(buf, 0);
  2751. } else if (opts.encoding === 'binary') {
  2752. ret = buf;
  2753. }
  2754. FS.close(stream);
  2755. return ret;
  2756. },writeFile:(path, data, opts = {}) => {
  2757. opts.flags = opts.flags || 577;
  2758. var stream = FS.open(path, opts.flags, opts.mode);
  2759. if (typeof data == 'string') {
  2760. var buf = new Uint8Array(lengthBytesUTF8(data)+1);
  2761. var actualNumBytes = stringToUTF8Array(data, buf, 0, buf.length);
  2762. FS.write(stream, buf, 0, actualNumBytes, undefined, opts.canOwn);
  2763. } else if (ArrayBuffer.isView(data)) {
  2764. FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn);
  2765. } else {
  2766. throw new Error('Unsupported data type');
  2767. }
  2768. FS.close(stream);
  2769. },cwd:() => FS.currentPath,chdir:(path) => {
  2770. var lookup = FS.lookupPath(path, { follow: true });
  2771. if (lookup.node === null) {
  2772. throw new FS.ErrnoError(44);
  2773. }
  2774. if (!FS.isDir(lookup.node.mode)) {
  2775. throw new FS.ErrnoError(54);
  2776. }
  2777. var errCode = FS.nodePermissions(lookup.node, 'x');
  2778. if (errCode) {
  2779. throw new FS.ErrnoError(errCode);
  2780. }
  2781. FS.currentPath = lookup.path;
  2782. },createDefaultDirectories:() => {
  2783. FS.mkdir('/tmp');
  2784. FS.mkdir('/home');
  2785. FS.mkdir('/home/web_user');
  2786. },createDefaultDevices:() => {
  2787. // create /dev
  2788. FS.mkdir('/dev');
  2789. // setup /dev/null
  2790. FS.registerDevice(FS.makedev(1, 3), {
  2791. read: () => 0,
  2792. write: (stream, buffer, offset, length, pos) => length,
  2793. });
  2794. FS.mkdev('/dev/null', FS.makedev(1, 3));
  2795. // setup /dev/tty and /dev/tty1
  2796. // stderr needs to print output using err() rather than out()
  2797. // so we register a second tty just for it.
  2798. TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
  2799. TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
  2800. FS.mkdev('/dev/tty', FS.makedev(5, 0));
  2801. FS.mkdev('/dev/tty1', FS.makedev(6, 0));
  2802. // setup /dev/[u]random
  2803. var random_device = getRandomDevice();
  2804. FS.createDevice('/dev', 'random', random_device);
  2805. FS.createDevice('/dev', 'urandom', random_device);
  2806. // we're not going to emulate the actual shm device,
  2807. // just create the tmp dirs that reside in it commonly
  2808. FS.mkdir('/dev/shm');
  2809. FS.mkdir('/dev/shm/tmp');
  2810. },createSpecialDirectories:() => {
  2811. // create /proc/self/fd which allows /proc/self/fd/6 => readlink gives the
  2812. // name of the stream for fd 6 (see test_unistd_ttyname)
  2813. FS.mkdir('/proc');
  2814. var proc_self = FS.mkdir('/proc/self');
  2815. FS.mkdir('/proc/self/fd');
  2816. FS.mount({
  2817. mount: () => {
  2818. var node = FS.createNode(proc_self, 'fd', 16384 | 511 /* 0777 */, 73);
  2819. node.node_ops = {
  2820. lookup: (parent, name) => {
  2821. var fd = +name;
  2822. var stream = FS.getStream(fd);
  2823. if (!stream) throw new FS.ErrnoError(8);
  2824. var ret = {
  2825. parent: null,
  2826. mount: { mountpoint: 'fake' },
  2827. node_ops: { readlink: () => stream.path },
  2828. };
  2829. ret.parent = ret; // make it look like a simple root node
  2830. return ret;
  2831. }
  2832. };
  2833. return node;
  2834. }
  2835. }, {}, '/proc/self/fd');
  2836. },createStandardStreams:() => {
  2837. // TODO deprecate the old functionality of a single
  2838. // input / output callback and that utilizes FS.createDevice
  2839. // and instead require a unique set of stream ops
  2840. // by default, we symlink the standard streams to the
  2841. // default tty devices. however, if the standard streams
  2842. // have been overwritten we create a unique device for
  2843. // them instead.
  2844. if (Module['stdin']) {
  2845. FS.createDevice('/dev', 'stdin', Module['stdin']);
  2846. } else {
  2847. FS.symlink('/dev/tty', '/dev/stdin');
  2848. }
  2849. if (Module['stdout']) {
  2850. FS.createDevice('/dev', 'stdout', null, Module['stdout']);
  2851. } else {
  2852. FS.symlink('/dev/tty', '/dev/stdout');
  2853. }
  2854. if (Module['stderr']) {
  2855. FS.createDevice('/dev', 'stderr', null, Module['stderr']);
  2856. } else {
  2857. FS.symlink('/dev/tty1', '/dev/stderr');
  2858. }
  2859. // open default streams for the stdin, stdout and stderr devices
  2860. var stdin = FS.open('/dev/stdin', 0);
  2861. var stdout = FS.open('/dev/stdout', 1);
  2862. var stderr = FS.open('/dev/stderr', 1);
  2863. assert(stdin.fd === 0, 'invalid handle for stdin (' + stdin.fd + ')');
  2864. assert(stdout.fd === 1, 'invalid handle for stdout (' + stdout.fd + ')');
  2865. assert(stderr.fd === 2, 'invalid handle for stderr (' + stderr.fd + ')');
  2866. },ensureErrnoError:() => {
  2867. if (FS.ErrnoError) return;
  2868. FS.ErrnoError = /** @this{Object} */ function ErrnoError(errno, node) {
  2869. this.node = node;
  2870. this.setErrno = /** @this{Object} */ function(errno) {
  2871. this.errno = errno;
  2872. for (var key in ERRNO_CODES) {
  2873. if (ERRNO_CODES[key] === errno) {
  2874. this.code = key;
  2875. break;
  2876. }
  2877. }
  2878. };
  2879. this.setErrno(errno);
  2880. this.message = ERRNO_MESSAGES[errno];
  2881. // Try to get a maximally helpful stack trace. On Node.js, getting Error.stack
  2882. // now ensures it shows what we want.
  2883. if (this.stack) {
  2884. // Define the stack property for Node.js 4, which otherwise errors on the next line.
  2885. Object.defineProperty(this, "stack", { value: (new Error).stack, writable: true });
  2886. this.stack = demangleAll(this.stack);
  2887. }
  2888. };
  2889. FS.ErrnoError.prototype = new Error();
  2890. FS.ErrnoError.prototype.constructor = FS.ErrnoError;
  2891. // Some errors may happen quite a bit, to avoid overhead we reuse them (and suffer a lack of stack info)
  2892. [44].forEach((code) => {
  2893. FS.genericErrors[code] = new FS.ErrnoError(code);
  2894. FS.genericErrors[code].stack = '<generic error, no stack>';
  2895. });
  2896. },staticInit:() => {
  2897. FS.ensureErrnoError();
  2898. FS.nameTable = new Array(4096);
  2899. FS.mount(MEMFS, {}, '/');
  2900. FS.createDefaultDirectories();
  2901. FS.createDefaultDevices();
  2902. FS.createSpecialDirectories();
  2903. FS.filesystems = {
  2904. 'MEMFS': MEMFS,
  2905. };
  2906. },init:(input, output, error) => {
  2907. assert(!FS.init.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)');
  2908. FS.init.initialized = true;
  2909. FS.ensureErrnoError();
  2910. // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here
  2911. Module['stdin'] = input || Module['stdin'];
  2912. Module['stdout'] = output || Module['stdout'];
  2913. Module['stderr'] = error || Module['stderr'];
  2914. FS.createStandardStreams();
  2915. },quit:() => {
  2916. FS.init.initialized = false;
  2917. // force-flush all streams, so we get musl std streams printed out
  2918. _fflush(0);
  2919. // close all of our streams
  2920. for (var i = 0; i < FS.streams.length; i++) {
  2921. var stream = FS.streams[i];
  2922. if (!stream) {
  2923. continue;
  2924. }
  2925. FS.close(stream);
  2926. }
  2927. },getMode:(canRead, canWrite) => {
  2928. var mode = 0;
  2929. if (canRead) mode |= 292 | 73;
  2930. if (canWrite) mode |= 146;
  2931. return mode;
  2932. },findObject:(path, dontResolveLastLink) => {
  2933. var ret = FS.analyzePath(path, dontResolveLastLink);
  2934. if (!ret.exists) {
  2935. return null;
  2936. }
  2937. return ret.object;
  2938. },analyzePath:(path, dontResolveLastLink) => {
  2939. // operate from within the context of the symlink's target
  2940. try {
  2941. var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
  2942. path = lookup.path;
  2943. } catch (e) {
  2944. }
  2945. var ret = {
  2946. isRoot: false, exists: false, error: 0, name: null, path: null, object: null,
  2947. parentExists: false, parentPath: null, parentObject: null
  2948. };
  2949. try {
  2950. var lookup = FS.lookupPath(path, { parent: true });
  2951. ret.parentExists = true;
  2952. ret.parentPath = lookup.path;
  2953. ret.parentObject = lookup.node;
  2954. ret.name = PATH.basename(path);
  2955. lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
  2956. ret.exists = true;
  2957. ret.path = lookup.path;
  2958. ret.object = lookup.node;
  2959. ret.name = lookup.node.name;
  2960. ret.isRoot = lookup.path === '/';
  2961. } catch (e) {
  2962. ret.error = e.errno;
  2963. };
  2964. return ret;
  2965. },createPath:(parent, path, canRead, canWrite) => {
  2966. parent = typeof parent == 'string' ? parent : FS.getPath(parent);
  2967. var parts = path.split('/').reverse();
  2968. while (parts.length) {
  2969. var part = parts.pop();
  2970. if (!part) continue;
  2971. var current = PATH.join2(parent, part);
  2972. try {
  2973. FS.mkdir(current);
  2974. } catch (e) {
  2975. // ignore EEXIST
  2976. }
  2977. parent = current;
  2978. }
  2979. return current;
  2980. },createFile:(parent, name, properties, canRead, canWrite) => {
  2981. var path = PATH.join2(typeof parent == 'string' ? parent : FS.getPath(parent), name);
  2982. var mode = FS.getMode(canRead, canWrite);
  2983. return FS.create(path, mode);
  2984. },createDataFile:(parent, name, data, canRead, canWrite, canOwn) => {
  2985. var path = name;
  2986. if (parent) {
  2987. parent = typeof parent == 'string' ? parent : FS.getPath(parent);
  2988. path = name ? PATH.join2(parent, name) : parent;
  2989. }
  2990. var mode = FS.getMode(canRead, canWrite);
  2991. var node = FS.create(path, mode);
  2992. if (data) {
  2993. if (typeof data == 'string') {
  2994. var arr = new Array(data.length);
  2995. for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
  2996. data = arr;
  2997. }
  2998. // make sure we can write to the file
  2999. FS.chmod(node, mode | 146);
  3000. var stream = FS.open(node, 577);
  3001. FS.write(stream, data, 0, data.length, 0, canOwn);
  3002. FS.close(stream);
  3003. FS.chmod(node, mode);
  3004. }
  3005. return node;
  3006. },createDevice:(parent, name, input, output) => {
  3007. var path = PATH.join2(typeof parent == 'string' ? parent : FS.getPath(parent), name);
  3008. var mode = FS.getMode(!!input, !!output);
  3009. if (!FS.createDevice.major) FS.createDevice.major = 64;
  3010. var dev = FS.makedev(FS.createDevice.major++, 0);
  3011. // Create a fake device that a set of stream ops to emulate
  3012. // the old behavior.
  3013. FS.registerDevice(dev, {
  3014. open: (stream) => {
  3015. stream.seekable = false;
  3016. },
  3017. close: (stream) => {
  3018. // flush any pending line data
  3019. if (output && output.buffer && output.buffer.length) {
  3020. output(10);
  3021. }
  3022. },
  3023. read: (stream, buffer, offset, length, pos /* ignored */) => {
  3024. var bytesRead = 0;
  3025. for (var i = 0; i < length; i++) {
  3026. var result;
  3027. try {
  3028. result = input();
  3029. } catch (e) {
  3030. throw new FS.ErrnoError(29);
  3031. }
  3032. if (result === undefined && bytesRead === 0) {
  3033. throw new FS.ErrnoError(6);
  3034. }
  3035. if (result === null || result === undefined) break;
  3036. bytesRead++;
  3037. buffer[offset+i] = result;
  3038. }
  3039. if (bytesRead) {
  3040. stream.node.timestamp = Date.now();
  3041. }
  3042. return bytesRead;
  3043. },
  3044. write: (stream, buffer, offset, length, pos) => {
  3045. for (var i = 0; i < length; i++) {
  3046. try {
  3047. output(buffer[offset+i]);
  3048. } catch (e) {
  3049. throw new FS.ErrnoError(29);
  3050. }
  3051. }
  3052. if (length) {
  3053. stream.node.timestamp = Date.now();
  3054. }
  3055. return i;
  3056. }
  3057. });
  3058. return FS.mkdev(path, mode, dev);
  3059. },forceLoadFile:(obj) => {
  3060. if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
  3061. if (typeof XMLHttpRequest != 'undefined') {
  3062. 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.");
  3063. } else if (read_) {
  3064. // Command-line.
  3065. try {
  3066. // WARNING: Can't read binary files in V8's d8 or tracemonkey's js, as
  3067. // read() will try to parse UTF8.
  3068. obj.contents = intArrayFromString(read_(obj.url), true);
  3069. obj.usedBytes = obj.contents.length;
  3070. } catch (e) {
  3071. throw new FS.ErrnoError(29);
  3072. }
  3073. } else {
  3074. throw new Error('Cannot load without read() or XMLHttpRequest.');
  3075. }
  3076. },createLazyFile:(parent, name, url, canRead, canWrite) => {
  3077. // Lazy chunked Uint8Array (implements get and length from Uint8Array). Actual getting is abstracted away for eventual reuse.
  3078. /** @constructor */
  3079. function LazyUint8Array() {
  3080. this.lengthKnown = false;
  3081. this.chunks = []; // Loaded chunks. Index is the chunk number
  3082. }
  3083. LazyUint8Array.prototype.get = /** @this{Object} */ function LazyUint8Array_get(idx) {
  3084. if (idx > this.length-1 || idx < 0) {
  3085. return undefined;
  3086. }
  3087. var chunkOffset = idx % this.chunkSize;
  3088. var chunkNum = (idx / this.chunkSize)|0;
  3089. return this.getter(chunkNum)[chunkOffset];
  3090. };
  3091. LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) {
  3092. this.getter = getter;
  3093. };
  3094. LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() {
  3095. // Find length
  3096. var xhr = new XMLHttpRequest();
  3097. xhr.open('HEAD', url, false);
  3098. xhr.send(null);
  3099. if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
  3100. var datalength = Number(xhr.getResponseHeader("Content-length"));
  3101. var header;
  3102. var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";
  3103. var usesGzip = (header = xhr.getResponseHeader("Content-Encoding")) && header === "gzip";
  3104. var chunkSize = 1024*1024; // Chunk size in bytes
  3105. if (!hasByteServing) chunkSize = datalength;
  3106. // Function to get a range from the remote URL.
  3107. var doXHR = (from, to) => {
  3108. if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!");
  3109. if (to > datalength-1) throw new Error("only " + datalength + " bytes available! programmer error!");
  3110. // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
  3111. var xhr = new XMLHttpRequest();
  3112. xhr.open('GET', url, false);
  3113. if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);
  3114. // Some hints to the browser that we want binary data.
  3115. xhr.responseType = 'arraybuffer';
  3116. if (xhr.overrideMimeType) {
  3117. xhr.overrideMimeType('text/plain; charset=x-user-defined');
  3118. }
  3119. xhr.send(null);
  3120. if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
  3121. if (xhr.response !== undefined) {
  3122. return new Uint8Array(/** @type{Array<number>} */(xhr.response || []));
  3123. }
  3124. return intArrayFromString(xhr.responseText || '', true);
  3125. };
  3126. var lazyArray = this;
  3127. lazyArray.setDataGetter((chunkNum) => {
  3128. var start = chunkNum * chunkSize;
  3129. var end = (chunkNum+1) * chunkSize - 1; // including this byte
  3130. end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block
  3131. if (typeof lazyArray.chunks[chunkNum] == 'undefined') {
  3132. lazyArray.chunks[chunkNum] = doXHR(start, end);
  3133. }
  3134. if (typeof lazyArray.chunks[chunkNum] == 'undefined') throw new Error('doXHR failed!');
  3135. return lazyArray.chunks[chunkNum];
  3136. });
  3137. if (usesGzip || !datalength) {
  3138. // if the server uses gzip or doesn't supply the length, we have to download the whole file to get the (uncompressed) length
  3139. chunkSize = datalength = 1; // this will force getter(0)/doXHR do download the whole file
  3140. datalength = this.getter(0).length;
  3141. chunkSize = datalength;
  3142. out("LazyFiles on gzip forces download of the whole file when length is accessed");
  3143. }
  3144. this._length = datalength;
  3145. this._chunkSize = chunkSize;
  3146. this.lengthKnown = true;
  3147. };
  3148. if (typeof XMLHttpRequest != 'undefined') {
  3149. if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc';
  3150. var lazyArray = new LazyUint8Array();
  3151. Object.defineProperties(lazyArray, {
  3152. length: {
  3153. get: /** @this{Object} */ function() {
  3154. if (!this.lengthKnown) {
  3155. this.cacheLength();
  3156. }
  3157. return this._length;
  3158. }
  3159. },
  3160. chunkSize: {
  3161. get: /** @this{Object} */ function() {
  3162. if (!this.lengthKnown) {
  3163. this.cacheLength();
  3164. }
  3165. return this._chunkSize;
  3166. }
  3167. }
  3168. });
  3169. var properties = { isDevice: false, contents: lazyArray };
  3170. } else {
  3171. var properties = { isDevice: false, url: url };
  3172. }
  3173. var node = FS.createFile(parent, name, properties, canRead, canWrite);
  3174. // This is a total hack, but I want to get this lazy file code out of the
  3175. // core of MEMFS. If we want to keep this lazy file concept I feel it should
  3176. // be its own thin LAZYFS proxying calls to MEMFS.
  3177. if (properties.contents) {
  3178. node.contents = properties.contents;
  3179. } else if (properties.url) {
  3180. node.contents = null;
  3181. node.url = properties.url;
  3182. }
  3183. // Add a function that defers querying the file size until it is asked the first time.
  3184. Object.defineProperties(node, {
  3185. usedBytes: {
  3186. get: /** @this {FSNode} */ function() { return this.contents.length; }
  3187. }
  3188. });
  3189. // override each stream op with one that tries to force load the lazy file first
  3190. var stream_ops = {};
  3191. var keys = Object.keys(node.stream_ops);
  3192. keys.forEach((key) => {
  3193. var fn = node.stream_ops[key];
  3194. stream_ops[key] = function forceLoadLazyFile() {
  3195. FS.forceLoadFile(node);
  3196. return fn.apply(null, arguments);
  3197. };
  3198. });
  3199. function writeChunks(stream, buffer, offset, length, position) {
  3200. var contents = stream.node.contents;
  3201. if (position >= contents.length)
  3202. return 0;
  3203. var size = Math.min(contents.length - position, length);
  3204. assert(size >= 0);
  3205. if (contents.slice) { // normal array
  3206. for (var i = 0; i < size; i++) {
  3207. buffer[offset + i] = contents[position + i];
  3208. }
  3209. } else {
  3210. for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR
  3211. buffer[offset + i] = contents.get(position + i);
  3212. }
  3213. }
  3214. return size;
  3215. }
  3216. // use a custom read function
  3217. stream_ops.read = (stream, buffer, offset, length, position) => {
  3218. FS.forceLoadFile(node);
  3219. return writeChunks(stream, buffer, offset, length, position)
  3220. };
  3221. // use a custom mmap function
  3222. stream_ops.mmap = (stream, length, position, prot, flags) => {
  3223. FS.forceLoadFile(node);
  3224. var ptr = mmapAlloc(length);
  3225. if (!ptr) {
  3226. throw new FS.ErrnoError(48);
  3227. }
  3228. writeChunks(stream, HEAP8, ptr, length, position);
  3229. return { ptr: ptr, allocated: true };
  3230. };
  3231. node.stream_ops = stream_ops;
  3232. return node;
  3233. },createPreloadedFile:(parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) => {
  3234. // TODO we should allow people to just pass in a complete filename instead
  3235. // of parent and name being that we just join them anyways
  3236. var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent;
  3237. var dep = getUniqueRunDependency('cp ' + fullname); // might have several active requests for the same fullname
  3238. function processData(byteArray) {
  3239. function finish(byteArray) {
  3240. if (preFinish) preFinish();
  3241. if (!dontCreateFile) {
  3242. FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
  3243. }
  3244. if (onload) onload();
  3245. removeRunDependency(dep);
  3246. }
  3247. if (Browser.handledByPreloadPlugin(byteArray, fullname, finish, () => {
  3248. if (onerror) onerror();
  3249. removeRunDependency(dep);
  3250. })) {
  3251. return;
  3252. }
  3253. finish(byteArray);
  3254. }
  3255. addRunDependency(dep);
  3256. if (typeof url == 'string') {
  3257. asyncLoad(url, (byteArray) => processData(byteArray), onerror);
  3258. } else {
  3259. processData(url);
  3260. }
  3261. },indexedDB:() => {
  3262. return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
  3263. },DB_NAME:() => {
  3264. return 'EM_FS_' + window.location.pathname;
  3265. },DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:(paths, onload, onerror) => {
  3266. onload = onload || (() => {});
  3267. onerror = onerror || (() => {});
  3268. var indexedDB = FS.indexedDB();
  3269. try {
  3270. var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
  3271. } catch (e) {
  3272. return onerror(e);
  3273. }
  3274. openRequest.onupgradeneeded = () => {
  3275. out('creating db');
  3276. var db = openRequest.result;
  3277. db.createObjectStore(FS.DB_STORE_NAME);
  3278. };
  3279. openRequest.onsuccess = () => {
  3280. var db = openRequest.result;
  3281. var transaction = db.transaction([FS.DB_STORE_NAME], 'readwrite');
  3282. var files = transaction.objectStore(FS.DB_STORE_NAME);
  3283. var ok = 0, fail = 0, total = paths.length;
  3284. function finish() {
  3285. if (fail == 0) onload(); else onerror();
  3286. }
  3287. paths.forEach((path) => {
  3288. var putRequest = files.put(FS.analyzePath(path).object.contents, path);
  3289. putRequest.onsuccess = () => { ok++; if (ok + fail == total) finish() };
  3290. putRequest.onerror = () => { fail++; if (ok + fail == total) finish() };
  3291. });
  3292. transaction.onerror = onerror;
  3293. };
  3294. openRequest.onerror = onerror;
  3295. },loadFilesFromDB:(paths, onload, onerror) => {
  3296. onload = onload || (() => {});
  3297. onerror = onerror || (() => {});
  3298. var indexedDB = FS.indexedDB();
  3299. try {
  3300. var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
  3301. } catch (e) {
  3302. return onerror(e);
  3303. }
  3304. openRequest.onupgradeneeded = onerror; // no database to load from
  3305. openRequest.onsuccess = () => {
  3306. var db = openRequest.result;
  3307. try {
  3308. var transaction = db.transaction([FS.DB_STORE_NAME], 'readonly');
  3309. } catch(e) {
  3310. onerror(e);
  3311. return;
  3312. }
  3313. var files = transaction.objectStore(FS.DB_STORE_NAME);
  3314. var ok = 0, fail = 0, total = paths.length;
  3315. function finish() {
  3316. if (fail == 0) onload(); else onerror();
  3317. }
  3318. paths.forEach((path) => {
  3319. var getRequest = files.get(path);
  3320. getRequest.onsuccess = () => {
  3321. if (FS.analyzePath(path).exists) {
  3322. FS.unlink(path);
  3323. }
  3324. FS.createDataFile(PATH.dirname(path), PATH.basename(path), getRequest.result, true, true, true);
  3325. ok++;
  3326. if (ok + fail == total) finish();
  3327. };
  3328. getRequest.onerror = () => { fail++; if (ok + fail == total) finish() };
  3329. });
  3330. transaction.onerror = onerror;
  3331. };
  3332. openRequest.onerror = onerror;
  3333. },absolutePath:() => {
  3334. abort('FS.absolutePath has been removed; use PATH_FS.resolve instead');
  3335. },createFolder:() => {
  3336. abort('FS.createFolder has been removed; use FS.mkdir instead');
  3337. },createLink:() => {
  3338. abort('FS.createLink has been removed; use FS.symlink instead');
  3339. },joinPath:() => {
  3340. abort('FS.joinPath has been removed; use PATH.join instead');
  3341. },mmapAlloc:() => {
  3342. abort('FS.mmapAlloc has been replaced by the top level function mmapAlloc');
  3343. },standardizePath:() => {
  3344. abort('FS.standardizePath has been removed; use PATH.normalize instead');
  3345. }};
  3346. var SYSCALLS = {DEFAULT_POLLMASK:5,calculateAt:function(dirfd, path, allowEmpty) {
  3347. if (PATH.isAbs(path)) {
  3348. return path;
  3349. }
  3350. // relative path
  3351. var dir;
  3352. if (dirfd === -100) {
  3353. dir = FS.cwd();
  3354. } else {
  3355. var dirstream = SYSCALLS.getStreamFromFD(dirfd);
  3356. dir = dirstream.path;
  3357. }
  3358. if (path.length == 0) {
  3359. if (!allowEmpty) {
  3360. throw new FS.ErrnoError(44);;
  3361. }
  3362. return dir;
  3363. }
  3364. return PATH.join2(dir, path);
  3365. },doStat:function(func, path, buf) {
  3366. try {
  3367. var stat = func(path);
  3368. } catch (e) {
  3369. if (e && e.node && PATH.normalize(path) !== PATH.normalize(FS.getPath(e.node))) {
  3370. // an error occurred while trying to look up the path; we should just report ENOTDIR
  3371. return -54;
  3372. }
  3373. throw e;
  3374. }
  3375. HEAP32[((buf)>>2)] = stat.dev;
  3376. HEAP32[(((buf)+(8))>>2)] = stat.ino;
  3377. HEAP32[(((buf)+(12))>>2)] = stat.mode;
  3378. HEAPU32[(((buf)+(16))>>2)] = stat.nlink;
  3379. HEAP32[(((buf)+(20))>>2)] = stat.uid;
  3380. HEAP32[(((buf)+(24))>>2)] = stat.gid;
  3381. HEAP32[(((buf)+(28))>>2)] = stat.rdev;
  3382. (tempI64 = [stat.size>>>0,(tempDouble=stat.size,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((buf)+(40))>>2)] = tempI64[0],HEAP32[(((buf)+(44))>>2)] = tempI64[1]);
  3383. HEAP32[(((buf)+(48))>>2)] = 4096;
  3384. HEAP32[(((buf)+(52))>>2)] = stat.blocks;
  3385. (tempI64 = [Math.floor(stat.atime.getTime() / 1000)>>>0,(tempDouble=Math.floor(stat.atime.getTime() / 1000),(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((buf)+(56))>>2)] = tempI64[0],HEAP32[(((buf)+(60))>>2)] = tempI64[1]);
  3386. HEAPU32[(((buf)+(64))>>2)] = 0;
  3387. (tempI64 = [Math.floor(stat.mtime.getTime() / 1000)>>>0,(tempDouble=Math.floor(stat.mtime.getTime() / 1000),(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((buf)+(72))>>2)] = tempI64[0],HEAP32[(((buf)+(76))>>2)] = tempI64[1]);
  3388. HEAPU32[(((buf)+(80))>>2)] = 0;
  3389. (tempI64 = [Math.floor(stat.ctime.getTime() / 1000)>>>0,(tempDouble=Math.floor(stat.ctime.getTime() / 1000),(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((buf)+(88))>>2)] = tempI64[0],HEAP32[(((buf)+(92))>>2)] = tempI64[1]);
  3390. HEAPU32[(((buf)+(96))>>2)] = 0;
  3391. (tempI64 = [stat.ino>>>0,(tempDouble=stat.ino,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((buf)+(104))>>2)] = tempI64[0],HEAP32[(((buf)+(108))>>2)] = tempI64[1]);
  3392. return 0;
  3393. },doMsync:function(addr, stream, len, flags, offset) {
  3394. if (!FS.isFile(stream.node.mode)) {
  3395. throw new FS.ErrnoError(43);
  3396. }
  3397. if (flags & 2) {
  3398. // MAP_PRIVATE calls need not to be synced back to underlying fs
  3399. return 0;
  3400. }
  3401. var buffer = HEAPU8.slice(addr, addr + len);
  3402. FS.msync(stream, buffer, offset, len, flags);
  3403. },varargs:undefined,get:function() {
  3404. assert(SYSCALLS.varargs != undefined);
  3405. SYSCALLS.varargs += 4;
  3406. var ret = HEAP32[(((SYSCALLS.varargs)-(4))>>2)];
  3407. return ret;
  3408. },getStr:function(ptr) {
  3409. var ret = UTF8ToString(ptr);
  3410. return ret;
  3411. },getStreamFromFD:function(fd) {
  3412. var stream = FS.getStream(fd);
  3413. if (!stream) throw new FS.ErrnoError(8);
  3414. return stream;
  3415. }};
  3416. function ___syscall_fcntl64(fd, cmd, varargs) {
  3417. SYSCALLS.varargs = varargs;
  3418. try {
  3419. var stream = SYSCALLS.getStreamFromFD(fd);
  3420. switch (cmd) {
  3421. case 0: {
  3422. var arg = SYSCALLS.get();
  3423. if (arg < 0) {
  3424. return -28;
  3425. }
  3426. var newStream;
  3427. newStream = FS.createStream(stream, arg);
  3428. return newStream.fd;
  3429. }
  3430. case 1:
  3431. case 2:
  3432. return 0; // FD_CLOEXEC makes no sense for a single process.
  3433. case 3:
  3434. return stream.flags;
  3435. case 4: {
  3436. var arg = SYSCALLS.get();
  3437. stream.flags |= arg;
  3438. return 0;
  3439. }
  3440. case 5:
  3441. /* case 5: Currently in musl F_GETLK64 has same value as F_GETLK, so omitted to avoid duplicate case blocks. If that changes, uncomment this */ {
  3442. var arg = SYSCALLS.get();
  3443. var offset = 0;
  3444. // We're always unlocked.
  3445. HEAP16[(((arg)+(offset))>>1)] = 2;
  3446. return 0;
  3447. }
  3448. case 6:
  3449. case 7:
  3450. /* case 6: Currently in musl F_SETLK64 has same value as F_SETLK, so omitted to avoid duplicate case blocks. If that changes, uncomment this */
  3451. /* case 7: Currently in musl F_SETLKW64 has same value as F_SETLKW, so omitted to avoid duplicate case blocks. If that changes, uncomment this */
  3452. return 0; // Pretend that the locking is successful.
  3453. case 16:
  3454. case 8:
  3455. return -28; // These are for sockets. We don't have them fully implemented yet.
  3456. case 9:
  3457. // musl trusts getown return values, due to a bug where they must be, as they overlap with errors. just return -1 here, so fcntl() returns that, and we set errno ourselves.
  3458. setErrNo(28);
  3459. return -1;
  3460. default: {
  3461. return -28;
  3462. }
  3463. }
  3464. } catch (e) {
  3465. if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
  3466. return -e.errno;
  3467. }
  3468. }
  3469. function ___syscall_ioctl(fd, op, varargs) {
  3470. SYSCALLS.varargs = varargs;
  3471. try {
  3472. var stream = SYSCALLS.getStreamFromFD(fd);
  3473. switch (op) {
  3474. case 21509:
  3475. case 21505: {
  3476. if (!stream.tty) return -59;
  3477. return 0;
  3478. }
  3479. case 21510:
  3480. case 21511:
  3481. case 21512:
  3482. case 21506:
  3483. case 21507:
  3484. case 21508: {
  3485. if (!stream.tty) return -59;
  3486. return 0; // no-op, not actually adjusting terminal settings
  3487. }
  3488. case 21519: {
  3489. if (!stream.tty) return -59;
  3490. var argp = SYSCALLS.get();
  3491. HEAP32[((argp)>>2)] = 0;
  3492. return 0;
  3493. }
  3494. case 21520: {
  3495. if (!stream.tty) return -59;
  3496. return -28; // not supported
  3497. }
  3498. case 21531: {
  3499. var argp = SYSCALLS.get();
  3500. return FS.ioctl(stream, op, argp);
  3501. }
  3502. case 21523: {
  3503. // TODO: in theory we should write to the winsize struct that gets
  3504. // passed in, but for now musl doesn't read anything on it
  3505. if (!stream.tty) return -59;
  3506. return 0;
  3507. }
  3508. case 21524: {
  3509. // TODO: technically, this ioctl call should change the window size.
  3510. // but, since emscripten doesn't have any concept of a terminal window
  3511. // yet, we'll just silently throw it away as we do TIOCGWINSZ
  3512. if (!stream.tty) return -59;
  3513. return 0;
  3514. }
  3515. default: return -28; // not supported
  3516. }
  3517. } catch (e) {
  3518. if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
  3519. return -e.errno;
  3520. }
  3521. }
  3522. function ___syscall_openat(dirfd, path, flags, varargs) {
  3523. SYSCALLS.varargs = varargs;
  3524. try {
  3525. path = SYSCALLS.getStr(path);
  3526. path = SYSCALLS.calculateAt(dirfd, path);
  3527. var mode = varargs ? SYSCALLS.get() : 0;
  3528. return FS.open(path, flags, mode).fd;
  3529. } catch (e) {
  3530. if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
  3531. return -e.errno;
  3532. }
  3533. }
  3534. var nowIsMonotonic = true;;
  3535. function __emscripten_get_now_is_monotonic() {
  3536. return nowIsMonotonic;
  3537. }
  3538. function runtimeKeepalivePush() {
  3539. runtimeKeepaliveCounter += 1;
  3540. }
  3541. function _emscripten_set_main_loop_timing(mode, value) {
  3542. Browser.mainLoop.timingMode = mode;
  3543. Browser.mainLoop.timingValue = value;
  3544. if (!Browser.mainLoop.func) {
  3545. 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.');
  3546. return 1; // Return non-zero on failure, can't set timing mode when there is no main loop.
  3547. }
  3548. if (!Browser.mainLoop.running) {
  3549. runtimeKeepalivePush();
  3550. Browser.mainLoop.running = true;
  3551. }
  3552. if (mode == 0 /*EM_TIMING_SETTIMEOUT*/) {
  3553. Browser.mainLoop.scheduler = function Browser_mainLoop_scheduler_setTimeout() {
  3554. var timeUntilNextTick = Math.max(0, Browser.mainLoop.tickStartTime + value - _emscripten_get_now())|0;
  3555. setTimeout(Browser.mainLoop.runner, timeUntilNextTick); // doing this each time means that on exception, we stop
  3556. };
  3557. Browser.mainLoop.method = 'timeout';
  3558. } else if (mode == 1 /*EM_TIMING_RAF*/) {
  3559. Browser.mainLoop.scheduler = function Browser_mainLoop_scheduler_rAF() {
  3560. Browser.requestAnimationFrame(Browser.mainLoop.runner);
  3561. };
  3562. Browser.mainLoop.method = 'rAF';
  3563. } else if (mode == 2 /*EM_TIMING_SETIMMEDIATE*/) {
  3564. if (typeof setImmediate == 'undefined') {
  3565. // Emulate setImmediate. (note: not a complete polyfill, we don't emulate clearImmediate() to keep code size to minimum, since not needed)
  3566. var setImmediates = [];
  3567. var emscriptenMainLoopMessageId = 'setimmediate';
  3568. /** @param {Event} event */
  3569. var Browser_setImmediate_messageHandler = (event) => {
  3570. // 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,
  3571. // so check for both cases.
  3572. if (event.data === emscriptenMainLoopMessageId || event.data.target === emscriptenMainLoopMessageId) {
  3573. event.stopPropagation();
  3574. setImmediates.shift()();
  3575. }
  3576. };
  3577. addEventListener("message", Browser_setImmediate_messageHandler, true);
  3578. setImmediate = /** @type{function(function(): ?, ...?): number} */(function Browser_emulated_setImmediate(func) {
  3579. setImmediates.push(func);
  3580. if (ENVIRONMENT_IS_WORKER) {
  3581. if (Module['setImmediates'] === undefined) Module['setImmediates'] = [];
  3582. Module['setImmediates'].push(func);
  3583. postMessage({target: emscriptenMainLoopMessageId}); // In --proxy-to-worker, route the message via proxyClient.js
  3584. } else postMessage(emscriptenMainLoopMessageId, "*"); // On the main thread, can just send the message to itself.
  3585. })
  3586. }
  3587. Browser.mainLoop.scheduler = function Browser_mainLoop_scheduler_setImmediate() {
  3588. setImmediate(Browser.mainLoop.runner);
  3589. };
  3590. Browser.mainLoop.method = 'immediate';
  3591. }
  3592. return 0;
  3593. }
  3594. var _emscripten_get_now;if (ENVIRONMENT_IS_NODE) {
  3595. _emscripten_get_now = () => {
  3596. var t = process['hrtime']();
  3597. return t[0] * 1e3 + t[1] / 1e6;
  3598. };
  3599. } else _emscripten_get_now = () => performance.now();
  3600. ;
  3601. function _proc_exit(code) {
  3602. EXITSTATUS = code;
  3603. if (!keepRuntimeAlive()) {
  3604. if (Module['onExit']) Module['onExit'](code);
  3605. ABORT = true;
  3606. }
  3607. quit_(code, new ExitStatus(code));
  3608. }
  3609. /** @param {boolean|number=} implicit */
  3610. function exitJS(status, implicit) {
  3611. EXITSTATUS = status;
  3612. if (!keepRuntimeAlive()) {
  3613. exitRuntime();
  3614. }
  3615. // if exit() was called explicitly, warn the user if the runtime isn't actually being shut down
  3616. if (keepRuntimeAlive() && !implicit) {
  3617. 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)';
  3618. err(msg);
  3619. }
  3620. _proc_exit(status);
  3621. }
  3622. var _exit = exitJS;
  3623. function handleException(e) {
  3624. // Certain exception types we do not treat as errors since they are used for
  3625. // internal control flow.
  3626. // 1. ExitStatus, which is thrown by exit()
  3627. // 2. "unwind", which is thrown by emscripten_unwind_to_js_event_loop() and others
  3628. // that wish to return to JS event loop.
  3629. if (e instanceof ExitStatus || e == 'unwind') {
  3630. return EXITSTATUS;
  3631. }
  3632. checkStackCookie();
  3633. if (e instanceof WebAssembly.RuntimeError) {
  3634. if (_emscripten_stack_get_current() <= 0) {
  3635. err('Stack overflow detected. You can try increasing -sSTACK_SIZE (currently set to ' + STACK_SIZE + ')');
  3636. }
  3637. }
  3638. quit_(1, e);
  3639. }
  3640. function maybeExit() {
  3641. if (!keepRuntimeAlive()) {
  3642. try {
  3643. _exit(EXITSTATUS);
  3644. } catch (e) {
  3645. handleException(e);
  3646. }
  3647. }
  3648. }
  3649. function runtimeKeepalivePop() {
  3650. assert(runtimeKeepaliveCounter > 0);
  3651. runtimeKeepaliveCounter -= 1;
  3652. }
  3653. /**
  3654. * @param {number=} arg
  3655. * @param {boolean=} noSetTiming
  3656. */
  3657. function setMainLoop(browserIterationFunc, fps, simulateInfiniteLoop, arg, noSetTiming) {
  3658. assert(!Browser.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.');
  3659. Browser.mainLoop.func = browserIterationFunc;
  3660. Browser.mainLoop.arg = arg;
  3661. var thisMainLoopId = Browser.mainLoop.currentlyRunningMainloop;
  3662. function checkIsRunning() {
  3663. if (thisMainLoopId < Browser.mainLoop.currentlyRunningMainloop) {
  3664. runtimeKeepalivePop();
  3665. maybeExit();
  3666. return false;
  3667. }
  3668. return true;
  3669. }
  3670. // We create the loop runner here but it is not actually running until
  3671. // _emscripten_set_main_loop_timing is called (which might happen a
  3672. // later time). This member signifies that the current runner has not
  3673. // yet been started so that we can call runtimeKeepalivePush when it
  3674. // gets it timing set for the first time.
  3675. Browser.mainLoop.running = false;
  3676. Browser.mainLoop.runner = function Browser_mainLoop_runner() {
  3677. if (ABORT) return;
  3678. if (Browser.mainLoop.queue.length > 0) {
  3679. var start = Date.now();
  3680. var blocker = Browser.mainLoop.queue.shift();
  3681. blocker.func(blocker.arg);
  3682. if (Browser.mainLoop.remainingBlockers) {
  3683. var remaining = Browser.mainLoop.remainingBlockers;
  3684. var next = remaining%1 == 0 ? remaining-1 : Math.floor(remaining);
  3685. if (blocker.counted) {
  3686. Browser.mainLoop.remainingBlockers = next;
  3687. } else {
  3688. // not counted, but move the progress along a tiny bit
  3689. next = next + 0.5; // do not steal all the next one's progress
  3690. Browser.mainLoop.remainingBlockers = (8*remaining + next)/9;
  3691. }
  3692. }
  3693. out('main loop blocker "' + blocker.name + '" took ' + (Date.now() - start) + ' ms'); //, left: ' + Browser.mainLoop.remainingBlockers);
  3694. Browser.mainLoop.updateStatus();
  3695. // catches pause/resume main loop from blocker execution
  3696. if (!checkIsRunning()) return;
  3697. setTimeout(Browser.mainLoop.runner, 0);
  3698. return;
  3699. }
  3700. // catch pauses from non-main loop sources
  3701. if (!checkIsRunning()) return;
  3702. // Implement very basic swap interval control
  3703. Browser.mainLoop.currentFrameNumber = Browser.mainLoop.currentFrameNumber + 1 | 0;
  3704. if (Browser.mainLoop.timingMode == 1/*EM_TIMING_RAF*/ && Browser.mainLoop.timingValue > 1 && Browser.mainLoop.currentFrameNumber % Browser.mainLoop.timingValue != 0) {
  3705. // Not the scheduled time to render this frame - skip.
  3706. Browser.mainLoop.scheduler();
  3707. return;
  3708. } else if (Browser.mainLoop.timingMode == 0/*EM_TIMING_SETTIMEOUT*/) {
  3709. Browser.mainLoop.tickStartTime = _emscripten_get_now();
  3710. }
  3711. // Signal GL rendering layer that processing of a new frame is about to start. This helps it optimize
  3712. // VBO double-buffering and reduce GPU stalls.
  3713. if (Browser.mainLoop.method === 'timeout' && Module.ctx) {
  3714. 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!');
  3715. Browser.mainLoop.method = ''; // just warn once per call to set main loop
  3716. }
  3717. Browser.mainLoop.runIter(browserIterationFunc);
  3718. checkStackCookie();
  3719. // catch pauses from the main loop itself
  3720. if (!checkIsRunning()) return;
  3721. // Queue new audio data. This is important to be right after the main loop invocation, so that we will immediately be able
  3722. // to queue the newest produced audio samples.
  3723. // TODO: Consider adding pre- and post- rAF callbacks so that GL.newRenderingFrameStarted() and SDL.audio.queueNewAudioData()
  3724. // do not need to be hardcoded into this function, but can be more generic.
  3725. if (typeof SDL == 'object' && SDL.audio && SDL.audio.queueNewAudioData) SDL.audio.queueNewAudioData();
  3726. Browser.mainLoop.scheduler();
  3727. }
  3728. if (!noSetTiming) {
  3729. if (fps && fps > 0) _emscripten_set_main_loop_timing(0/*EM_TIMING_SETTIMEOUT*/, 1000.0 / fps);
  3730. else _emscripten_set_main_loop_timing(1/*EM_TIMING_RAF*/, 1); // Do rAF by rendering each frame (no decimating)
  3731. Browser.mainLoop.scheduler();
  3732. }
  3733. if (simulateInfiniteLoop) {
  3734. throw 'unwind';
  3735. }
  3736. }
  3737. function callUserCallback(func) {
  3738. if (runtimeExited || ABORT) {
  3739. err('user callback triggered after runtime exited or application aborted. Ignoring.');
  3740. return;
  3741. }
  3742. try {
  3743. func();
  3744. maybeExit();
  3745. } catch (e) {
  3746. handleException(e);
  3747. }
  3748. }
  3749. /** @param {number=} timeout */
  3750. function safeSetTimeout(func, timeout) {
  3751. runtimeKeepalivePush();
  3752. return setTimeout(function() {
  3753. runtimeKeepalivePop();
  3754. callUserCallback(func);
  3755. }, timeout);
  3756. }
  3757. var Browser = {mainLoop:{running:false,scheduler:null,method:"",currentlyRunningMainloop:0,func:null,arg:0,timingMode:0,timingValue:0,currentFrameNumber:0,queue:[],pause:function() {
  3758. Browser.mainLoop.scheduler = null;
  3759. // Incrementing this signals the previous main loop that it's now become old, and it must return.
  3760. Browser.mainLoop.currentlyRunningMainloop++;
  3761. },resume:function() {
  3762. Browser.mainLoop.currentlyRunningMainloop++;
  3763. var timingMode = Browser.mainLoop.timingMode;
  3764. var timingValue = Browser.mainLoop.timingValue;
  3765. var func = Browser.mainLoop.func;
  3766. Browser.mainLoop.func = null;
  3767. // do not set timing and call scheduler, we will do it on the next lines
  3768. setMainLoop(func, 0, false, Browser.mainLoop.arg, true);
  3769. _emscripten_set_main_loop_timing(timingMode, timingValue);
  3770. Browser.mainLoop.scheduler();
  3771. },updateStatus:function() {
  3772. if (Module['setStatus']) {
  3773. var message = Module['statusMessage'] || 'Please wait...';
  3774. var remaining = Browser.mainLoop.remainingBlockers;
  3775. var expected = Browser.mainLoop.expectedBlockers;
  3776. if (remaining) {
  3777. if (remaining < expected) {
  3778. Module['setStatus'](message + ' (' + (expected - remaining) + '/' + expected + ')');
  3779. } else {
  3780. Module['setStatus'](message);
  3781. }
  3782. } else {
  3783. Module['setStatus']('');
  3784. }
  3785. }
  3786. },runIter:function(func) {
  3787. if (ABORT) return;
  3788. if (Module['preMainLoop']) {
  3789. var preRet = Module['preMainLoop']();
  3790. if (preRet === false) {
  3791. return; // |return false| skips a frame
  3792. }
  3793. }
  3794. callUserCallback(func);
  3795. if (Module['postMainLoop']) Module['postMainLoop']();
  3796. }},isFullscreen:false,pointerLock:false,moduleContextCreatedCallbacks:[],workers:[],init:function() {
  3797. if (!Module["preloadPlugins"]) Module["preloadPlugins"] = []; // needs to exist even in workers
  3798. if (Browser.initted) return;
  3799. Browser.initted = true;
  3800. try {
  3801. new Blob();
  3802. Browser.hasBlobConstructor = true;
  3803. } catch(e) {
  3804. Browser.hasBlobConstructor = false;
  3805. err("warning: no blob constructor, cannot create blobs with mimetypes");
  3806. }
  3807. Browser.BlobBuilder = typeof MozBlobBuilder != "undefined" ? MozBlobBuilder : (typeof WebKitBlobBuilder != "undefined" ? WebKitBlobBuilder : (!Browser.hasBlobConstructor ? err("warning: no BlobBuilder") : null));
  3808. Browser.URLObject = typeof window != "undefined" ? (window.URL ? window.URL : window.webkitURL) : undefined;
  3809. if (!Module.noImageDecoding && typeof Browser.URLObject == 'undefined') {
  3810. err("warning: Browser does not support creating object URLs. Built-in browser image decoding will not be available.");
  3811. Module.noImageDecoding = true;
  3812. }
  3813. // Support for plugins that can process preloaded files. You can add more of these to
  3814. // your app by creating and appending to Module.preloadPlugins.
  3815. //
  3816. // Each plugin is asked if it can handle a file based on the file's name. If it can,
  3817. // it is given the file's raw data. When it is done, it calls a callback with the file's
  3818. // (possibly modified) data. For example, a plugin might decompress a file, or it
  3819. // might create some side data structure for use later (like an Image element, etc.).
  3820. var imagePlugin = {};
  3821. imagePlugin['canHandle'] = function imagePlugin_canHandle(name) {
  3822. return !Module.noImageDecoding && /\.(jpg|jpeg|png|bmp)$/i.test(name);
  3823. };
  3824. imagePlugin['handle'] = function imagePlugin_handle(byteArray, name, onload, onerror) {
  3825. var b = null;
  3826. if (Browser.hasBlobConstructor) {
  3827. try {
  3828. b = new Blob([byteArray], { type: Browser.getMimetype(name) });
  3829. if (b.size !== byteArray.length) { // Safari bug #118630
  3830. // Safari's Blob can only take an ArrayBuffer
  3831. b = new Blob([(new Uint8Array(byteArray)).buffer], { type: Browser.getMimetype(name) });
  3832. }
  3833. } catch(e) {
  3834. warnOnce('Blob constructor present but fails: ' + e + '; falling back to blob builder');
  3835. }
  3836. }
  3837. if (!b) {
  3838. var bb = new Browser.BlobBuilder();
  3839. bb.append((new Uint8Array(byteArray)).buffer); // we need to pass a buffer, and must copy the array to get the right data range
  3840. b = bb.getBlob();
  3841. }
  3842. var url = Browser.URLObject.createObjectURL(b);
  3843. assert(typeof url == 'string', 'createObjectURL must return a url as a string');
  3844. var img = new Image();
  3845. img.onload = () => {
  3846. assert(img.complete, 'Image ' + name + ' could not be decoded');
  3847. var canvas = /** @type {!HTMLCanvasElement} */ (document.createElement('canvas'));
  3848. canvas.width = img.width;
  3849. canvas.height = img.height;
  3850. var ctx = canvas.getContext('2d');
  3851. ctx.drawImage(img, 0, 0);
  3852. preloadedImages[name] = canvas;
  3853. Browser.URLObject.revokeObjectURL(url);
  3854. if (onload) onload(byteArray);
  3855. };
  3856. img.onerror = (event) => {
  3857. out('Image ' + url + ' could not be decoded');
  3858. if (onerror) onerror();
  3859. };
  3860. img.src = url;
  3861. };
  3862. Module['preloadPlugins'].push(imagePlugin);
  3863. var audioPlugin = {};
  3864. audioPlugin['canHandle'] = function audioPlugin_canHandle(name) {
  3865. return !Module.noAudioDecoding && name.substr(-4) in { '.ogg': 1, '.wav': 1, '.mp3': 1 };
  3866. };
  3867. audioPlugin['handle'] = function audioPlugin_handle(byteArray, name, onload, onerror) {
  3868. var done = false;
  3869. function finish(audio) {
  3870. if (done) return;
  3871. done = true;
  3872. preloadedAudios[name] = audio;
  3873. if (onload) onload(byteArray);
  3874. }
  3875. function fail() {
  3876. if (done) return;
  3877. done = true;
  3878. preloadedAudios[name] = new Audio(); // empty shim
  3879. if (onerror) onerror();
  3880. }
  3881. if (Browser.hasBlobConstructor) {
  3882. try {
  3883. var b = new Blob([byteArray], { type: Browser.getMimetype(name) });
  3884. } catch(e) {
  3885. return fail();
  3886. }
  3887. var url = Browser.URLObject.createObjectURL(b); // XXX we never revoke this!
  3888. assert(typeof url == 'string', 'createObjectURL must return a url as a string');
  3889. var audio = new Audio();
  3890. audio.addEventListener('canplaythrough', () => finish(audio), false); // use addEventListener due to chromium bug 124926
  3891. audio.onerror = function audio_onerror(event) {
  3892. if (done) return;
  3893. err('warning: browser could not fully decode audio ' + name + ', trying slower base64 approach');
  3894. function encode64(data) {
  3895. var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  3896. var PAD = '=';
  3897. var ret = '';
  3898. var leftchar = 0;
  3899. var leftbits = 0;
  3900. for (var i = 0; i < data.length; i++) {
  3901. leftchar = (leftchar << 8) | data[i];
  3902. leftbits += 8;
  3903. while (leftbits >= 6) {
  3904. var curr = (leftchar >> (leftbits-6)) & 0x3f;
  3905. leftbits -= 6;
  3906. ret += BASE[curr];
  3907. }
  3908. }
  3909. if (leftbits == 2) {
  3910. ret += BASE[(leftchar&3) << 4];
  3911. ret += PAD + PAD;
  3912. } else if (leftbits == 4) {
  3913. ret += BASE[(leftchar&0xf) << 2];
  3914. ret += PAD;
  3915. }
  3916. return ret;
  3917. }
  3918. audio.src = 'data:audio/x-' + name.substr(-3) + ';base64,' + encode64(byteArray);
  3919. finish(audio); // we don't wait for confirmation this worked - but it's worth trying
  3920. };
  3921. audio.src = url;
  3922. // workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror
  3923. safeSetTimeout(function() {
  3924. finish(audio); // try to use it even though it is not necessarily ready to play
  3925. }, 10000);
  3926. } else {
  3927. return fail();
  3928. }
  3929. };
  3930. Module['preloadPlugins'].push(audioPlugin);
  3931. // Canvas event setup
  3932. function pointerLockChange() {
  3933. Browser.pointerLock = document['pointerLockElement'] === Module['canvas'] ||
  3934. document['mozPointerLockElement'] === Module['canvas'] ||
  3935. document['webkitPointerLockElement'] === Module['canvas'] ||
  3936. document['msPointerLockElement'] === Module['canvas'];
  3937. }
  3938. var canvas = Module['canvas'];
  3939. if (canvas) {
  3940. // forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module
  3941. // Module['forcedAspectRatio'] = 4 / 3;
  3942. canvas.requestPointerLock = canvas['requestPointerLock'] ||
  3943. canvas['mozRequestPointerLock'] ||
  3944. canvas['webkitRequestPointerLock'] ||
  3945. canvas['msRequestPointerLock'] ||
  3946. (() => {});
  3947. canvas.exitPointerLock = document['exitPointerLock'] ||
  3948. document['mozExitPointerLock'] ||
  3949. document['webkitExitPointerLock'] ||
  3950. document['msExitPointerLock'] ||
  3951. (() => {}); // no-op if function does not exist
  3952. canvas.exitPointerLock = canvas.exitPointerLock.bind(document);
  3953. document.addEventListener('pointerlockchange', pointerLockChange, false);
  3954. document.addEventListener('mozpointerlockchange', pointerLockChange, false);
  3955. document.addEventListener('webkitpointerlockchange', pointerLockChange, false);
  3956. document.addEventListener('mspointerlockchange', pointerLockChange, false);
  3957. if (Module['elementPointerLock']) {
  3958. canvas.addEventListener("click", (ev) => {
  3959. if (!Browser.pointerLock && Module['canvas'].requestPointerLock) {
  3960. Module['canvas'].requestPointerLock();
  3961. ev.preventDefault();
  3962. }
  3963. }, false);
  3964. }
  3965. }
  3966. },handledByPreloadPlugin:function(byteArray, fullname, finish, onerror) {
  3967. // Ensure plugins are ready.
  3968. Browser.init();
  3969. var handled = false;
  3970. Module['preloadPlugins'].forEach(function(plugin) {
  3971. if (handled) return;
  3972. if (plugin['canHandle'](fullname)) {
  3973. plugin['handle'](byteArray, fullname, finish, onerror);
  3974. handled = true;
  3975. }
  3976. });
  3977. return handled;
  3978. },createContext:function(/** @type {HTMLCanvasElement} */ canvas, useWebGL, setInModule, webGLContextAttributes) {
  3979. if (useWebGL && Module.ctx && canvas == Module.canvas) return Module.ctx; // no need to recreate GL context if it's already been created for this canvas.
  3980. var ctx;
  3981. var contextHandle;
  3982. if (useWebGL) {
  3983. // For GLES2/desktop GL compatibility, adjust a few defaults to be different to WebGL defaults, so that they align better with the desktop defaults.
  3984. var contextAttributes = {
  3985. antialias: false,
  3986. alpha: false,
  3987. majorVersion: 1,
  3988. };
  3989. if (webGLContextAttributes) {
  3990. for (var attribute in webGLContextAttributes) {
  3991. contextAttributes[attribute] = webGLContextAttributes[attribute];
  3992. }
  3993. }
  3994. // 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
  3995. // actually compiled in because application is not doing any GL operations. TODO: Ideally if GL is not being used, this function
  3996. // Browser.createContext() should not even be emitted.
  3997. if (typeof GL != 'undefined') {
  3998. contextHandle = GL.createContext(canvas, contextAttributes);
  3999. if (contextHandle) {
  4000. ctx = GL.getContext(contextHandle).GLctx;
  4001. }
  4002. }
  4003. } else {
  4004. ctx = canvas.getContext('2d');
  4005. }
  4006. if (!ctx) return null;
  4007. if (setInModule) {
  4008. 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');
  4009. Module.ctx = ctx;
  4010. if (useWebGL) GL.makeContextCurrent(contextHandle);
  4011. Module.useWebGL = useWebGL;
  4012. Browser.moduleContextCreatedCallbacks.forEach(function(callback) { callback() });
  4013. Browser.init();
  4014. }
  4015. return ctx;
  4016. },destroyContext:function(canvas, useWebGL, setInModule) {},fullscreenHandlersInstalled:false,lockPointer:undefined,resizeCanvas:undefined,requestFullscreen:function(lockPointer, resizeCanvas) {
  4017. Browser.lockPointer = lockPointer;
  4018. Browser.resizeCanvas = resizeCanvas;
  4019. if (typeof Browser.lockPointer == 'undefined') Browser.lockPointer = true;
  4020. if (typeof Browser.resizeCanvas == 'undefined') Browser.resizeCanvas = false;
  4021. var canvas = Module['canvas'];
  4022. function fullscreenChange() {
  4023. Browser.isFullscreen = false;
  4024. var canvasContainer = canvas.parentNode;
  4025. if ((document['fullscreenElement'] || document['mozFullScreenElement'] ||
  4026. document['msFullscreenElement'] || document['webkitFullscreenElement'] ||
  4027. document['webkitCurrentFullScreenElement']) === canvasContainer) {
  4028. canvas.exitFullscreen = Browser.exitFullscreen;
  4029. if (Browser.lockPointer) canvas.requestPointerLock();
  4030. Browser.isFullscreen = true;
  4031. if (Browser.resizeCanvas) {
  4032. Browser.setFullscreenCanvasSize();
  4033. } else {
  4034. Browser.updateCanvasDimensions(canvas);
  4035. }
  4036. } else {
  4037. // remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen
  4038. canvasContainer.parentNode.insertBefore(canvas, canvasContainer);
  4039. canvasContainer.parentNode.removeChild(canvasContainer);
  4040. if (Browser.resizeCanvas) {
  4041. Browser.setWindowedCanvasSize();
  4042. } else {
  4043. Browser.updateCanvasDimensions(canvas);
  4044. }
  4045. }
  4046. if (Module['onFullScreen']) Module['onFullScreen'](Browser.isFullscreen);
  4047. if (Module['onFullscreen']) Module['onFullscreen'](Browser.isFullscreen);
  4048. }
  4049. if (!Browser.fullscreenHandlersInstalled) {
  4050. Browser.fullscreenHandlersInstalled = true;
  4051. document.addEventListener('fullscreenchange', fullscreenChange, false);
  4052. document.addEventListener('mozfullscreenchange', fullscreenChange, false);
  4053. document.addEventListener('webkitfullscreenchange', fullscreenChange, false);
  4054. document.addEventListener('MSFullscreenChange', fullscreenChange, false);
  4055. }
  4056. // 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
  4057. var canvasContainer = document.createElement("div");
  4058. canvas.parentNode.insertBefore(canvasContainer, canvas);
  4059. canvasContainer.appendChild(canvas);
  4060. // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size)
  4061. canvasContainer.requestFullscreen = canvasContainer['requestFullscreen'] ||
  4062. canvasContainer['mozRequestFullScreen'] ||
  4063. canvasContainer['msRequestFullscreen'] ||
  4064. (canvasContainer['webkitRequestFullscreen'] ? () => canvasContainer['webkitRequestFullscreen'](Element['ALLOW_KEYBOARD_INPUT']) : null) ||
  4065. (canvasContainer['webkitRequestFullScreen'] ? () => canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) : null);
  4066. canvasContainer.requestFullscreen();
  4067. },requestFullScreen:function() {
  4068. abort('Module.requestFullScreen has been replaced by Module.requestFullscreen (without a capital S)');
  4069. },exitFullscreen:function() {
  4070. // This is workaround for chrome. Trying to exit from fullscreen
  4071. // not in fullscreen state will cause "TypeError: Document not active"
  4072. // in chrome. See https://github.com/emscripten-core/emscripten/pull/8236
  4073. if (!Browser.isFullscreen) {
  4074. return false;
  4075. }
  4076. var CFS = document['exitFullscreen'] ||
  4077. document['cancelFullScreen'] ||
  4078. document['mozCancelFullScreen'] ||
  4079. document['msExitFullscreen'] ||
  4080. document['webkitCancelFullScreen'] ||
  4081. (function() {});
  4082. CFS.apply(document, []);
  4083. return true;
  4084. },nextRAF:0,fakeRequestAnimationFrame:function(func) {
  4085. // try to keep 60fps between calls to here
  4086. var now = Date.now();
  4087. if (Browser.nextRAF === 0) {
  4088. Browser.nextRAF = now + 1000/60;
  4089. } else {
  4090. while (now + 2 >= Browser.nextRAF) { // fudge a little, to avoid timer jitter causing us to do lots of delay:0
  4091. Browser.nextRAF += 1000/60;
  4092. }
  4093. }
  4094. var delay = Math.max(Browser.nextRAF - now, 0);
  4095. setTimeout(func, delay);
  4096. },requestAnimationFrame:function(func) {
  4097. if (typeof requestAnimationFrame == 'function') {
  4098. requestAnimationFrame(func);
  4099. return;
  4100. }
  4101. var RAF = Browser.fakeRequestAnimationFrame;
  4102. RAF(func);
  4103. },safeSetTimeout:function(func, timeout) {
  4104. // Legacy function, this is used by the SDL2 port so we need to keep it
  4105. // around at least until that is updated.
  4106. // See https://github.com/libsdl-org/SDL/pull/6304
  4107. return safeSetTimeout(func, timeout);
  4108. },safeRequestAnimationFrame:function(func) {
  4109. runtimeKeepalivePush();
  4110. return Browser.requestAnimationFrame(function() {
  4111. runtimeKeepalivePop();
  4112. callUserCallback(func);
  4113. });
  4114. },getMimetype:function(name) {
  4115. return {
  4116. 'jpg': 'image/jpeg',
  4117. 'jpeg': 'image/jpeg',
  4118. 'png': 'image/png',
  4119. 'bmp': 'image/bmp',
  4120. 'ogg': 'audio/ogg',
  4121. 'wav': 'audio/wav',
  4122. 'mp3': 'audio/mpeg'
  4123. }[name.substr(name.lastIndexOf('.')+1)];
  4124. },getUserMedia:function(func) {
  4125. if (!window.getUserMedia) {
  4126. window.getUserMedia = navigator['getUserMedia'] ||
  4127. navigator['mozGetUserMedia'];
  4128. }
  4129. window.getUserMedia(func);
  4130. },getMovementX:function(event) {
  4131. return event['movementX'] ||
  4132. event['mozMovementX'] ||
  4133. event['webkitMovementX'] ||
  4134. 0;
  4135. },getMovementY:function(event) {
  4136. return event['movementY'] ||
  4137. event['mozMovementY'] ||
  4138. event['webkitMovementY'] ||
  4139. 0;
  4140. },getMouseWheelDelta:function(event) {
  4141. var delta = 0;
  4142. switch (event.type) {
  4143. case 'DOMMouseScroll':
  4144. // 3 lines make up a step
  4145. delta = event.detail / 3;
  4146. break;
  4147. case 'mousewheel':
  4148. // 120 units make up a step
  4149. delta = event.wheelDelta / 120;
  4150. break;
  4151. case 'wheel':
  4152. delta = event.deltaY
  4153. switch (event.deltaMode) {
  4154. case 0:
  4155. // DOM_DELTA_PIXEL: 100 pixels make up a step
  4156. delta /= 100;
  4157. break;
  4158. case 1:
  4159. // DOM_DELTA_LINE: 3 lines make up a step
  4160. delta /= 3;
  4161. break;
  4162. case 2:
  4163. // DOM_DELTA_PAGE: A page makes up 80 steps
  4164. delta *= 80;
  4165. break;
  4166. default:
  4167. throw 'unrecognized mouse wheel delta mode: ' + event.deltaMode;
  4168. }
  4169. break;
  4170. default:
  4171. throw 'unrecognized mouse wheel event: ' + event.type;
  4172. }
  4173. return delta;
  4174. },mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,touches:{},lastTouches:{},calculateMouseEvent:function(event) { // event should be mousemove, mousedown or mouseup
  4175. if (Browser.pointerLock) {
  4176. // When the pointer is locked, calculate the coordinates
  4177. // based on the movement of the mouse.
  4178. // Workaround for Firefox bug 764498
  4179. if (event.type != 'mousemove' &&
  4180. ('mozMovementX' in event)) {
  4181. Browser.mouseMovementX = Browser.mouseMovementY = 0;
  4182. } else {
  4183. Browser.mouseMovementX = Browser.getMovementX(event);
  4184. Browser.mouseMovementY = Browser.getMovementY(event);
  4185. }
  4186. // check if SDL is available
  4187. if (typeof SDL != "undefined") {
  4188. Browser.mouseX = SDL.mouseX + Browser.mouseMovementX;
  4189. Browser.mouseY = SDL.mouseY + Browser.mouseMovementY;
  4190. } else {
  4191. // just add the mouse delta to the current absolut mouse position
  4192. // FIXME: ideally this should be clamped against the canvas size and zero
  4193. Browser.mouseX += Browser.mouseMovementX;
  4194. Browser.mouseY += Browser.mouseMovementY;
  4195. }
  4196. } else {
  4197. // Otherwise, calculate the movement based on the changes
  4198. // in the coordinates.
  4199. var rect = Module["canvas"].getBoundingClientRect();
  4200. var cw = Module["canvas"].width;
  4201. var ch = Module["canvas"].height;
  4202. // Neither .scrollX or .pageXOffset are defined in a spec, but
  4203. // we prefer .scrollX because it is currently in a spec draft.
  4204. // (see: http://www.w3.org/TR/2013/WD-cssom-view-20131217/)
  4205. var scrollX = ((typeof window.scrollX != 'undefined') ? window.scrollX : window.pageXOffset);
  4206. var scrollY = ((typeof window.scrollY != 'undefined') ? window.scrollY : window.pageYOffset);
  4207. // If this assert lands, it's likely because the browser doesn't support scrollX or pageXOffset
  4208. // and we have no viable fallback.
  4209. assert((typeof scrollX != 'undefined') && (typeof scrollY != 'undefined'), 'Unable to retrieve scroll position, mouse positions likely broken.');
  4210. if (event.type === 'touchstart' || event.type === 'touchend' || event.type === 'touchmove') {
  4211. var touch = event.touch;
  4212. if (touch === undefined) {
  4213. return; // the "touch" property is only defined in SDL
  4214. }
  4215. var adjustedX = touch.pageX - (scrollX + rect.left);
  4216. var adjustedY = touch.pageY - (scrollY + rect.top);
  4217. adjustedX = adjustedX * (cw / rect.width);
  4218. adjustedY = adjustedY * (ch / rect.height);
  4219. var coords = { x: adjustedX, y: adjustedY };
  4220. if (event.type === 'touchstart') {
  4221. Browser.lastTouches[touch.identifier] = coords;
  4222. Browser.touches[touch.identifier] = coords;
  4223. } else if (event.type === 'touchend' || event.type === 'touchmove') {
  4224. var last = Browser.touches[touch.identifier];
  4225. if (!last) last = coords;
  4226. Browser.lastTouches[touch.identifier] = last;
  4227. Browser.touches[touch.identifier] = coords;
  4228. }
  4229. return;
  4230. }
  4231. var x = event.pageX - (scrollX + rect.left);
  4232. var y = event.pageY - (scrollY + rect.top);
  4233. // the canvas might be CSS-scaled compared to its backbuffer;
  4234. // SDL-using content will want mouse coordinates in terms
  4235. // of backbuffer units.
  4236. x = x * (cw / rect.width);
  4237. y = y * (ch / rect.height);
  4238. Browser.mouseMovementX = x - Browser.mouseX;
  4239. Browser.mouseMovementY = y - Browser.mouseY;
  4240. Browser.mouseX = x;
  4241. Browser.mouseY = y;
  4242. }
  4243. },resizeListeners:[],updateResizeListeners:function() {
  4244. var canvas = Module['canvas'];
  4245. Browser.resizeListeners.forEach(function(listener) {
  4246. listener(canvas.width, canvas.height);
  4247. });
  4248. },setCanvasSize:function(width, height, noUpdates) {
  4249. var canvas = Module['canvas'];
  4250. Browser.updateCanvasDimensions(canvas, width, height);
  4251. if (!noUpdates) Browser.updateResizeListeners();
  4252. },windowedWidth:0,windowedHeight:0,setFullscreenCanvasSize:function() {
  4253. // check if SDL is available
  4254. if (typeof SDL != "undefined") {
  4255. var flags = HEAPU32[((SDL.screen)>>2)];
  4256. flags = flags | 0x00800000; // set SDL_FULLSCREEN flag
  4257. HEAP32[((SDL.screen)>>2)] = flags;
  4258. }
  4259. Browser.updateCanvasDimensions(Module['canvas']);
  4260. Browser.updateResizeListeners();
  4261. },setWindowedCanvasSize:function() {
  4262. // check if SDL is available
  4263. if (typeof SDL != "undefined") {
  4264. var flags = HEAPU32[((SDL.screen)>>2)];
  4265. flags = flags & ~0x00800000; // clear SDL_FULLSCREEN flag
  4266. HEAP32[((SDL.screen)>>2)] = flags;
  4267. }
  4268. Browser.updateCanvasDimensions(Module['canvas']);
  4269. Browser.updateResizeListeners();
  4270. },updateCanvasDimensions:function(canvas, wNative, hNative) {
  4271. if (wNative && hNative) {
  4272. canvas.widthNative = wNative;
  4273. canvas.heightNative = hNative;
  4274. } else {
  4275. wNative = canvas.widthNative;
  4276. hNative = canvas.heightNative;
  4277. }
  4278. var w = wNative;
  4279. var h = hNative;
  4280. if (Module['forcedAspectRatio'] && Module['forcedAspectRatio'] > 0) {
  4281. if (w/h < Module['forcedAspectRatio']) {
  4282. w = Math.round(h * Module['forcedAspectRatio']);
  4283. } else {
  4284. h = Math.round(w / Module['forcedAspectRatio']);
  4285. }
  4286. }
  4287. if (((document['fullscreenElement'] || document['mozFullScreenElement'] ||
  4288. document['msFullscreenElement'] || document['webkitFullscreenElement'] ||
  4289. document['webkitCurrentFullScreenElement']) === canvas.parentNode) && (typeof screen != 'undefined')) {
  4290. var factor = Math.min(screen.width / w, screen.height / h);
  4291. w = Math.round(w * factor);
  4292. h = Math.round(h * factor);
  4293. }
  4294. if (Browser.resizeCanvas) {
  4295. if (canvas.width != w) canvas.width = w;
  4296. if (canvas.height != h) canvas.height = h;
  4297. if (typeof canvas.style != 'undefined') {
  4298. canvas.style.removeProperty( "width");
  4299. canvas.style.removeProperty("height");
  4300. }
  4301. } else {
  4302. if (canvas.width != wNative) canvas.width = wNative;
  4303. if (canvas.height != hNative) canvas.height = hNative;
  4304. if (typeof canvas.style != 'undefined') {
  4305. if (w != wNative || h != hNative) {
  4306. canvas.style.setProperty( "width", w + "px", "important");
  4307. canvas.style.setProperty("height", h + "px", "important");
  4308. } else {
  4309. canvas.style.removeProperty( "width");
  4310. canvas.style.removeProperty("height");
  4311. }
  4312. }
  4313. }
  4314. }};
  4315. var EGL = {errorCode:12288,defaultDisplayInitialized:false,currentContext:0,currentReadSurface:0,currentDrawSurface:0,contextAttributes:{alpha:false,depth:false,stencil:false,antialias:false},stringCache:{},setErrorCode:function(code) {
  4316. EGL.errorCode = code;
  4317. },chooseConfig:function(display, attribList, config, config_size, numConfigs) {
  4318. if (display != 62000 /* Magic ID for Emscripten 'default display' */) {
  4319. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  4320. return 0;
  4321. }
  4322. if (attribList) {
  4323. // read attribList if it is non-null
  4324. for (;;) {
  4325. var param = HEAP32[((attribList)>>2)];
  4326. if (param == 0x3021 /*EGL_ALPHA_SIZE*/) {
  4327. var alphaSize = HEAP32[(((attribList)+(4))>>2)];
  4328. EGL.contextAttributes.alpha = (alphaSize > 0);
  4329. } else if (param == 0x3025 /*EGL_DEPTH_SIZE*/) {
  4330. var depthSize = HEAP32[(((attribList)+(4))>>2)];
  4331. EGL.contextAttributes.depth = (depthSize > 0);
  4332. } else if (param == 0x3026 /*EGL_STENCIL_SIZE*/) {
  4333. var stencilSize = HEAP32[(((attribList)+(4))>>2)];
  4334. EGL.contextAttributes.stencil = (stencilSize > 0);
  4335. } else if (param == 0x3031 /*EGL_SAMPLES*/) {
  4336. var samples = HEAP32[(((attribList)+(4))>>2)];
  4337. EGL.contextAttributes.antialias = (samples > 0);
  4338. } else if (param == 0x3032 /*EGL_SAMPLE_BUFFERS*/) {
  4339. var samples = HEAP32[(((attribList)+(4))>>2)];
  4340. EGL.contextAttributes.antialias = (samples == 1);
  4341. } else if (param == 0x3100 /*EGL_CONTEXT_PRIORITY_LEVEL_IMG*/) {
  4342. var requestedPriority = HEAP32[(((attribList)+(4))>>2)];
  4343. EGL.contextAttributes.lowLatency = (requestedPriority != 0x3103 /*EGL_CONTEXT_PRIORITY_LOW_IMG*/);
  4344. } else if (param == 0x3038 /*EGL_NONE*/) {
  4345. break;
  4346. }
  4347. attribList += 8;
  4348. }
  4349. }
  4350. if ((!config || !config_size) && !numConfigs) {
  4351. EGL.setErrorCode(0x300C /* EGL_BAD_PARAMETER */);
  4352. return 0;
  4353. }
  4354. if (numConfigs) {
  4355. HEAP32[((numConfigs)>>2)] = 1; // Total number of supported configs: 1.
  4356. }
  4357. if (config && config_size > 0) {
  4358. HEAP32[((config)>>2)] = 62002;
  4359. }
  4360. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4361. return 1;
  4362. }};
  4363. function _eglBindAPI(api) {
  4364. if (api == 0x30A0 /* EGL_OPENGL_ES_API */) {
  4365. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4366. return 1;
  4367. }
  4368. // if (api == 0x30A1 /* EGL_OPENVG_API */ || api == 0x30A2 /* EGL_OPENGL_API */) {
  4369. EGL.setErrorCode(0x300C /* EGL_BAD_PARAMETER */);
  4370. return 0;
  4371. }
  4372. function _eglChooseConfig(display, attrib_list, configs, config_size, numConfigs) {
  4373. return EGL.chooseConfig(display, attrib_list, configs, config_size, numConfigs);
  4374. }
  4375. function __webgl_enable_ANGLE_instanced_arrays(ctx) {
  4376. // Extension available in WebGL 1 from Firefox 26 and Google Chrome 30 onwards. Core feature in WebGL 2.
  4377. var ext = ctx.getExtension('ANGLE_instanced_arrays');
  4378. if (ext) {
  4379. ctx['vertexAttribDivisor'] = function(index, divisor) { ext['vertexAttribDivisorANGLE'](index, divisor); };
  4380. ctx['drawArraysInstanced'] = function(mode, first, count, primcount) { ext['drawArraysInstancedANGLE'](mode, first, count, primcount); };
  4381. ctx['drawElementsInstanced'] = function(mode, count, type, indices, primcount) { ext['drawElementsInstancedANGLE'](mode, count, type, indices, primcount); };
  4382. return 1;
  4383. }
  4384. }
  4385. function __webgl_enable_OES_vertex_array_object(ctx) {
  4386. // Extension available in WebGL 1 from Firefox 25 and WebKit 536.28/desktop Safari 6.0.3 onwards. Core feature in WebGL 2.
  4387. var ext = ctx.getExtension('OES_vertex_array_object');
  4388. if (ext) {
  4389. ctx['createVertexArray'] = function() { return ext['createVertexArrayOES'](); };
  4390. ctx['deleteVertexArray'] = function(vao) { ext['deleteVertexArrayOES'](vao); };
  4391. ctx['bindVertexArray'] = function(vao) { ext['bindVertexArrayOES'](vao); };
  4392. ctx['isVertexArray'] = function(vao) { return ext['isVertexArrayOES'](vao); };
  4393. return 1;
  4394. }
  4395. }
  4396. function __webgl_enable_WEBGL_draw_buffers(ctx) {
  4397. // Extension available in WebGL 1 from Firefox 28 onwards. Core feature in WebGL 2.
  4398. var ext = ctx.getExtension('WEBGL_draw_buffers');
  4399. if (ext) {
  4400. ctx['drawBuffers'] = function(n, bufs) { ext['drawBuffersWEBGL'](n, bufs); };
  4401. return 1;
  4402. }
  4403. }
  4404. function __webgl_enable_WEBGL_multi_draw(ctx) {
  4405. // Closure is expected to be allowed to minify the '.multiDrawWebgl' property, so not accessing it quoted.
  4406. return !!(ctx.multiDrawWebgl = ctx.getExtension('WEBGL_multi_draw'));
  4407. }
  4408. var GL = {counter:1,buffers:[],programs:[],framebuffers:[],renderbuffers:[],textures:[],shaders:[],vaos:[],contexts:[],offscreenCanvases:{},queries:[],stringCache:{},unpackAlignment:4,recordError:function recordError(errorCode) {
  4409. if (!GL.lastError) {
  4410. GL.lastError = errorCode;
  4411. }
  4412. },getNewId:function(table) {
  4413. var ret = GL.counter++;
  4414. for (var i = table.length; i < ret; i++) {
  4415. table[i] = null;
  4416. }
  4417. return ret;
  4418. },getSource:function(shader, count, string, length) {
  4419. var source = '';
  4420. for (var i = 0; i < count; ++i) {
  4421. var len = length ? HEAP32[(((length)+(i*4))>>2)] : -1;
  4422. source += UTF8ToString(HEAP32[(((string)+(i*4))>>2)], len < 0 ? undefined : len);
  4423. }
  4424. return source;
  4425. },createContext:function(/** @type {HTMLCanvasElement} */ canvas, webGLContextAttributes) {
  4426. // BUG: Workaround Safari WebGL issue: After successfully acquiring WebGL context on a canvas,
  4427. // calling .getContext() will always return that context independent of which 'webgl' or 'webgl2'
  4428. // context version was passed. See https://bugs.webkit.org/show_bug.cgi?id=222758 and
  4429. // https://github.com/emscripten-core/emscripten/issues/13295.
  4430. // TODO: Once the bug is fixed and shipped in Safari, adjust the Safari version field in above check.
  4431. if (!canvas.getContextSafariWebGL2Fixed) {
  4432. canvas.getContextSafariWebGL2Fixed = canvas.getContext;
  4433. /** @type {function(this:HTMLCanvasElement, string, (Object|null)=): (Object|null)} */
  4434. function fixedGetContext(ver, attrs) {
  4435. var gl = canvas.getContextSafariWebGL2Fixed(ver, attrs);
  4436. return ((ver == 'webgl') == (gl instanceof WebGLRenderingContext)) ? gl : null;
  4437. }
  4438. canvas.getContext = fixedGetContext;
  4439. }
  4440. var ctx =
  4441. (canvas.getContext("webgl", webGLContextAttributes)
  4442. // https://caniuse.com/#feat=webgl
  4443. );
  4444. if (!ctx) return 0;
  4445. var handle = GL.registerContext(ctx, webGLContextAttributes);
  4446. return handle;
  4447. },registerContext:function(ctx, webGLContextAttributes) {
  4448. // without pthreads a context is just an integer ID
  4449. var handle = GL.getNewId(GL.contexts);
  4450. var context = {
  4451. handle: handle,
  4452. attributes: webGLContextAttributes,
  4453. version: webGLContextAttributes.majorVersion,
  4454. GLctx: ctx
  4455. };
  4456. // Store the created context object so that we can access the context given a canvas without having to pass the parameters again.
  4457. if (ctx.canvas) ctx.canvas.GLctxObject = context;
  4458. GL.contexts[handle] = context;
  4459. if (typeof webGLContextAttributes.enableExtensionsByDefault == 'undefined' || webGLContextAttributes.enableExtensionsByDefault) {
  4460. GL.initExtensions(context);
  4461. }
  4462. return handle;
  4463. },makeContextCurrent:function(contextHandle) {
  4464. GL.currentContext = GL.contexts[contextHandle]; // Active Emscripten GL layer context object.
  4465. Module.ctx = GLctx = GL.currentContext && GL.currentContext.GLctx; // Active WebGL context object.
  4466. return !(contextHandle && !GLctx);
  4467. },getContext:function(contextHandle) {
  4468. return GL.contexts[contextHandle];
  4469. },deleteContext:function(contextHandle) {
  4470. if (GL.currentContext === GL.contexts[contextHandle]) GL.currentContext = null;
  4471. if (typeof JSEvents == 'object') JSEvents.removeAllHandlersOnTarget(GL.contexts[contextHandle].GLctx.canvas); // Release all JS event handlers on the DOM element that the GL context is associated with since the context is now deleted.
  4472. if (GL.contexts[contextHandle] && GL.contexts[contextHandle].GLctx.canvas) GL.contexts[contextHandle].GLctx.canvas.GLctxObject = undefined; // Make sure the canvas object no longer refers to the context object so there are no GC surprises.
  4473. GL.contexts[contextHandle] = null;
  4474. },initExtensions:function(context) {
  4475. // If this function is called without a specific context object, init the extensions of the currently active context.
  4476. if (!context) context = GL.currentContext;
  4477. if (context.initExtensionsDone) return;
  4478. context.initExtensionsDone = true;
  4479. var GLctx = context.GLctx;
  4480. // Detect the presence of a few extensions manually, this GL interop layer itself will need to know if they exist.
  4481. // Extensions that are only available in WebGL 1 (the calls will be no-ops if called on a WebGL 2 context active)
  4482. __webgl_enable_ANGLE_instanced_arrays(GLctx);
  4483. __webgl_enable_OES_vertex_array_object(GLctx);
  4484. __webgl_enable_WEBGL_draw_buffers(GLctx);
  4485. {
  4486. GLctx.disjointTimerQueryExt = GLctx.getExtension("EXT_disjoint_timer_query");
  4487. }
  4488. __webgl_enable_WEBGL_multi_draw(GLctx);
  4489. // .getSupportedExtensions() can return null if context is lost, so coerce to empty array.
  4490. var exts = GLctx.getSupportedExtensions() || [];
  4491. exts.forEach(function(ext) {
  4492. // WEBGL_lose_context, WEBGL_debug_renderer_info and WEBGL_debug_shaders are not enabled by default.
  4493. if (!ext.includes('lose_context') && !ext.includes('debug')) {
  4494. // Call .getExtension() to enable that extension permanently.
  4495. GLctx.getExtension(ext);
  4496. }
  4497. });
  4498. }};
  4499. function _eglCreateContext(display, config, hmm, contextAttribs) {
  4500. if (display != 62000 /* Magic ID for Emscripten 'default display' */) {
  4501. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  4502. return 0;
  4503. }
  4504. // EGL 1.4 spec says default EGL_CONTEXT_CLIENT_VERSION is GLES1, but this is not supported by Emscripten.
  4505. // So user must pass EGL_CONTEXT_CLIENT_VERSION == 2 to initialize EGL.
  4506. var glesContextVersion = 1;
  4507. for (;;) {
  4508. var param = HEAP32[((contextAttribs)>>2)];
  4509. if (param == 0x3098 /*EGL_CONTEXT_CLIENT_VERSION*/) {
  4510. glesContextVersion = HEAP32[(((contextAttribs)+(4))>>2)];
  4511. } else if (param == 0x3038 /*EGL_NONE*/) {
  4512. break;
  4513. } else {
  4514. /* EGL1.4 specifies only EGL_CONTEXT_CLIENT_VERSION as supported attribute */
  4515. EGL.setErrorCode(0x3004 /*EGL_BAD_ATTRIBUTE*/);
  4516. return 0;
  4517. }
  4518. contextAttribs += 8;
  4519. }
  4520. if (glesContextVersion != 2) {
  4521. EGL.setErrorCode(0x3005 /* EGL_BAD_CONFIG */);
  4522. return 0; /* EGL_NO_CONTEXT */
  4523. }
  4524. EGL.contextAttributes.majorVersion = glesContextVersion - 1; // WebGL 1 is GLES 2, WebGL2 is GLES3
  4525. EGL.contextAttributes.minorVersion = 0;
  4526. EGL.context = GL.createContext(Module['canvas'], EGL.contextAttributes);
  4527. if (EGL.context != 0) {
  4528. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4529. // Run callbacks so that GL emulation works
  4530. GL.makeContextCurrent(EGL.context);
  4531. Module.useWebGL = true;
  4532. Browser.moduleContextCreatedCallbacks.forEach(function(callback) { callback() });
  4533. // Note: This function only creates a context, but it shall not make it active.
  4534. GL.makeContextCurrent(null);
  4535. return 62004; // Magic ID for Emscripten EGLContext
  4536. } else {
  4537. EGL.setErrorCode(0x3009 /* EGL_BAD_MATCH */); // By the EGL 1.4 spec, an implementation that does not support GLES2 (WebGL in this case), this error code is set.
  4538. return 0; /* EGL_NO_CONTEXT */
  4539. }
  4540. }
  4541. function _eglCreateWindowSurface(display, config, win, attrib_list) {
  4542. if (display != 62000 /* Magic ID for Emscripten 'default display' */) {
  4543. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  4544. return 0;
  4545. }
  4546. if (config != 62002 /* Magic ID for the only EGLConfig supported by Emscripten */) {
  4547. EGL.setErrorCode(0x3005 /* EGL_BAD_CONFIG */);
  4548. return 0;
  4549. }
  4550. // TODO: Examine attrib_list! Parameters that can be present there are:
  4551. // - EGL_RENDER_BUFFER (must be EGL_BACK_BUFFER)
  4552. // - EGL_VG_COLORSPACE (can't be set)
  4553. // - EGL_VG_ALPHA_FORMAT (can't be set)
  4554. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4555. return 62006; /* Magic ID for Emscripten 'default surface' */
  4556. }
  4557. function _eglDestroyContext(display, context) {
  4558. if (display != 62000 /* Magic ID for Emscripten 'default display' */) {
  4559. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  4560. return 0;
  4561. }
  4562. if (context != 62004 /* Magic ID for Emscripten EGLContext */) {
  4563. EGL.setErrorCode(0x3006 /* EGL_BAD_CONTEXT */);
  4564. return 0;
  4565. }
  4566. GL.deleteContext(EGL.context);
  4567. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4568. if (EGL.currentContext == context) {
  4569. EGL.currentContext = 0;
  4570. }
  4571. return 1 /* EGL_TRUE */;
  4572. }
  4573. function _eglDestroySurface(display, surface) {
  4574. if (display != 62000 /* Magic ID for Emscripten 'default display' */) {
  4575. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  4576. return 0;
  4577. }
  4578. if (surface != 62006 /* Magic ID for the only EGLSurface supported by Emscripten */) {
  4579. EGL.setErrorCode(0x300D /* EGL_BAD_SURFACE */);
  4580. return 1;
  4581. }
  4582. if (EGL.currentReadSurface == surface) {
  4583. EGL.currentReadSurface = 0;
  4584. }
  4585. if (EGL.currentDrawSurface == surface) {
  4586. EGL.currentDrawSurface = 0;
  4587. }
  4588. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4589. return 1; /* Magic ID for Emscripten 'default surface' */
  4590. }
  4591. function _eglGetConfigAttrib(display, config, attribute, value) {
  4592. if (display != 62000 /* Magic ID for Emscripten 'default display' */) {
  4593. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  4594. return 0;
  4595. }
  4596. if (config != 62002 /* Magic ID for the only EGLConfig supported by Emscripten */) {
  4597. EGL.setErrorCode(0x3005 /* EGL_BAD_CONFIG */);
  4598. return 0;
  4599. }
  4600. if (!value) {
  4601. EGL.setErrorCode(0x300C /* EGL_BAD_PARAMETER */);
  4602. return 0;
  4603. }
  4604. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4605. switch (attribute) {
  4606. case 0x3020: // EGL_BUFFER_SIZE
  4607. HEAP32[((value)>>2)] = EGL.contextAttributes.alpha ? 32 : 24;
  4608. return 1;
  4609. case 0x3021: // EGL_ALPHA_SIZE
  4610. HEAP32[((value)>>2)] = EGL.contextAttributes.alpha ? 8 : 0;
  4611. return 1;
  4612. case 0x3022: // EGL_BLUE_SIZE
  4613. HEAP32[((value)>>2)] = 8;
  4614. return 1;
  4615. case 0x3023: // EGL_GREEN_SIZE
  4616. HEAP32[((value)>>2)] = 8;
  4617. return 1;
  4618. case 0x3024: // EGL_RED_SIZE
  4619. HEAP32[((value)>>2)] = 8;
  4620. return 1;
  4621. case 0x3025: // EGL_DEPTH_SIZE
  4622. HEAP32[((value)>>2)] = EGL.contextAttributes.depth ? 24 : 0;
  4623. return 1;
  4624. case 0x3026: // EGL_STENCIL_SIZE
  4625. HEAP32[((value)>>2)] = EGL.contextAttributes.stencil ? 8 : 0;
  4626. return 1;
  4627. case 0x3027: // EGL_CONFIG_CAVEAT
  4628. // We can return here one of EGL_NONE (0x3038), EGL_SLOW_CONFIG (0x3050) or EGL_NON_CONFORMANT_CONFIG (0x3051).
  4629. HEAP32[((value)>>2)] = 0x3038;
  4630. return 1;
  4631. case 0x3028: // EGL_CONFIG_ID
  4632. HEAP32[((value)>>2)] = 62002;
  4633. return 1;
  4634. case 0x3029: // EGL_LEVEL
  4635. HEAP32[((value)>>2)] = 0;
  4636. return 1;
  4637. case 0x302A: // EGL_MAX_PBUFFER_HEIGHT
  4638. HEAP32[((value)>>2)] = 4096;
  4639. return 1;
  4640. case 0x302B: // EGL_MAX_PBUFFER_PIXELS
  4641. HEAP32[((value)>>2)] = 16777216;
  4642. return 1;
  4643. case 0x302C: // EGL_MAX_PBUFFER_WIDTH
  4644. HEAP32[((value)>>2)] = 4096;
  4645. return 1;
  4646. case 0x302D: // EGL_NATIVE_RENDERABLE
  4647. HEAP32[((value)>>2)] = 0;
  4648. return 1;
  4649. case 0x302E: // EGL_NATIVE_VISUAL_ID
  4650. HEAP32[((value)>>2)] = 0;
  4651. return 1;
  4652. case 0x302F: // EGL_NATIVE_VISUAL_TYPE
  4653. HEAP32[((value)>>2)] = 0x3038;
  4654. return 1;
  4655. case 0x3031: // EGL_SAMPLES
  4656. HEAP32[((value)>>2)] = EGL.contextAttributes.antialias ? 4 : 0;
  4657. return 1;
  4658. case 0x3032: // EGL_SAMPLE_BUFFERS
  4659. HEAP32[((value)>>2)] = EGL.contextAttributes.antialias ? 1 : 0;
  4660. return 1;
  4661. case 0x3033: // EGL_SURFACE_TYPE
  4662. HEAP32[((value)>>2)] = 0x4;
  4663. return 1;
  4664. case 0x3034: // EGL_TRANSPARENT_TYPE
  4665. // If this returns EGL_TRANSPARENT_RGB (0x3052), transparency is used through color-keying. No such thing applies to Emscripten canvas.
  4666. HEAP32[((value)>>2)] = 0x3038;
  4667. return 1;
  4668. case 0x3035: // EGL_TRANSPARENT_BLUE_VALUE
  4669. case 0x3036: // EGL_TRANSPARENT_GREEN_VALUE
  4670. case 0x3037: // EGL_TRANSPARENT_RED_VALUE
  4671. // "If EGL_TRANSPARENT_TYPE is EGL_NONE, then the values for EGL_TRANSPARENT_RED_VALUE, EGL_TRANSPARENT_GREEN_VALUE, and EGL_TRANSPARENT_BLUE_VALUE are undefined."
  4672. HEAP32[((value)>>2)] = -1;
  4673. return 1;
  4674. case 0x3039: // EGL_BIND_TO_TEXTURE_RGB
  4675. case 0x303A: // EGL_BIND_TO_TEXTURE_RGBA
  4676. HEAP32[((value)>>2)] = 0;
  4677. return 1;
  4678. case 0x303B: // EGL_MIN_SWAP_INTERVAL
  4679. HEAP32[((value)>>2)] = 0;
  4680. return 1;
  4681. case 0x303C: // EGL_MAX_SWAP_INTERVAL
  4682. HEAP32[((value)>>2)] = 1;
  4683. return 1;
  4684. case 0x303D: // EGL_LUMINANCE_SIZE
  4685. case 0x303E: // EGL_ALPHA_MASK_SIZE
  4686. HEAP32[((value)>>2)] = 0;
  4687. return 1;
  4688. case 0x303F: // EGL_COLOR_BUFFER_TYPE
  4689. // EGL has two types of buffers: EGL_RGB_BUFFER and EGL_LUMINANCE_BUFFER.
  4690. HEAP32[((value)>>2)] = 0x308E;
  4691. return 1;
  4692. case 0x3040: // EGL_RENDERABLE_TYPE
  4693. // A bit combination of EGL_OPENGL_ES_BIT,EGL_OPENVG_BIT,EGL_OPENGL_ES2_BIT and EGL_OPENGL_BIT.
  4694. HEAP32[((value)>>2)] = 0x4;
  4695. return 1;
  4696. case 0x3042: // EGL_CONFORMANT
  4697. // "EGL_CONFORMANT is a mask indicating if a client API context created with respect to the corresponding EGLConfig will pass the required conformance tests for that API."
  4698. HEAP32[((value)>>2)] = 0;
  4699. return 1;
  4700. default:
  4701. EGL.setErrorCode(0x3004 /* EGL_BAD_ATTRIBUTE */);
  4702. return 0;
  4703. }
  4704. }
  4705. function _eglGetDisplay(nativeDisplayType) {
  4706. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4707. // Note: As a 'conformant' implementation of EGL, we would prefer to init here only if the user
  4708. // calls this function with EGL_DEFAULT_DISPLAY. Other display IDs would be preferred to be unsupported
  4709. // and EGL_NO_DISPLAY returned. Uncomment the following code lines to do this.
  4710. // Instead, an alternative route has been preferred, namely that the Emscripten EGL implementation
  4711. // "emulates" X11, and eglGetDisplay is expected to accept/receive a pointer to an X11 Display object.
  4712. // Therefore, be lax and allow anything to be passed in, and return the magic handle to our default EGLDisplay object.
  4713. // if (nativeDisplayType == 0 /* EGL_DEFAULT_DISPLAY */) {
  4714. return 62000; // Magic ID for Emscripten 'default display'
  4715. // }
  4716. // else
  4717. // return 0; // EGL_NO_DISPLAY
  4718. }
  4719. function _eglGetError() {
  4720. return EGL.errorCode;
  4721. }
  4722. function _eglInitialize(display, majorVersion, minorVersion) {
  4723. if (display != 62000 /* Magic ID for Emscripten 'default display' */) {
  4724. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  4725. return 0;
  4726. }
  4727. if (majorVersion) {
  4728. HEAP32[((majorVersion)>>2)] = 1; // Advertise EGL Major version: '1'
  4729. }
  4730. if (minorVersion) {
  4731. HEAP32[((minorVersion)>>2)] = 4; // Advertise EGL Minor version: '4'
  4732. }
  4733. EGL.defaultDisplayInitialized = true;
  4734. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4735. return 1;
  4736. }
  4737. function _eglMakeCurrent(display, draw, read, context) {
  4738. if (display != 62000 /* Magic ID for Emscripten 'default display' */) {
  4739. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  4740. return 0 /* EGL_FALSE */;
  4741. }
  4742. //\todo An EGL_NOT_INITIALIZED error is generated if EGL is not initialized for dpy.
  4743. if (context != 0 && context != 62004 /* Magic ID for Emscripten EGLContext */) {
  4744. EGL.setErrorCode(0x3006 /* EGL_BAD_CONTEXT */);
  4745. return 0;
  4746. }
  4747. if ((read != 0 && read != 62006) || (draw != 0 && draw != 62006 /* Magic ID for Emscripten 'default surface' */)) {
  4748. EGL.setErrorCode(0x300D /* EGL_BAD_SURFACE */);
  4749. return 0;
  4750. }
  4751. GL.makeContextCurrent(context ? EGL.context : null);
  4752. EGL.currentContext = context;
  4753. EGL.currentDrawSurface = draw;
  4754. EGL.currentReadSurface = read;
  4755. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4756. return 1 /* EGL_TRUE */;
  4757. }
  4758. function allocateUTF8(str) {
  4759. var size = lengthBytesUTF8(str) + 1;
  4760. var ret = _malloc(size);
  4761. if (ret) stringToUTF8Array(str, HEAP8, ret, size);
  4762. return ret;
  4763. }
  4764. function _eglQueryString(display, name) {
  4765. if (display != 62000 /* Magic ID for Emscripten 'default display' */) {
  4766. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  4767. return 0;
  4768. }
  4769. //\todo An EGL_NOT_INITIALIZED error is generated if EGL is not initialized for dpy.
  4770. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4771. if (EGL.stringCache[name]) return EGL.stringCache[name];
  4772. var ret;
  4773. switch (name) {
  4774. case 0x3053 /* EGL_VENDOR */: ret = allocateUTF8("Emscripten"); break;
  4775. case 0x3054 /* EGL_VERSION */: ret = allocateUTF8("1.4 Emscripten EGL"); break;
  4776. case 0x3055 /* EGL_EXTENSIONS */: ret = allocateUTF8(""); break; // Currently not supporting any EGL extensions.
  4777. case 0x308D /* EGL_CLIENT_APIS */: ret = allocateUTF8("OpenGL_ES"); break;
  4778. default:
  4779. EGL.setErrorCode(0x300C /* EGL_BAD_PARAMETER */);
  4780. return 0;
  4781. }
  4782. EGL.stringCache[name] = ret;
  4783. return ret;
  4784. }
  4785. function _eglSwapBuffers() {
  4786. if (!EGL.defaultDisplayInitialized) {
  4787. EGL.setErrorCode(0x3001 /* EGL_NOT_INITIALIZED */);
  4788. } else if (!Module.ctx) {
  4789. EGL.setErrorCode(0x3002 /* EGL_BAD_ACCESS */);
  4790. } else if (Module.ctx.isContextLost()) {
  4791. EGL.setErrorCode(0x300E /* EGL_CONTEXT_LOST */);
  4792. } else {
  4793. // According to documentation this does an implicit flush.
  4794. // Due to discussion at https://github.com/emscripten-core/emscripten/pull/1871
  4795. // the flush was removed since this _may_ result in slowing code down.
  4796. //_glFlush();
  4797. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4798. return 1 /* EGL_TRUE */;
  4799. }
  4800. return 0 /* EGL_FALSE */;
  4801. }
  4802. function _eglSwapInterval(display, interval) {
  4803. if (display != 62000 /* Magic ID for Emscripten 'default display' */) {
  4804. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  4805. return 0;
  4806. }
  4807. if (interval == 0) _emscripten_set_main_loop_timing(0/*EM_TIMING_SETTIMEOUT*/, 0);
  4808. else _emscripten_set_main_loop_timing(1/*EM_TIMING_RAF*/, interval);
  4809. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4810. return 1;
  4811. }
  4812. function _eglTerminate(display) {
  4813. if (display != 62000 /* Magic ID for Emscripten 'default display' */) {
  4814. EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */);
  4815. return 0;
  4816. }
  4817. EGL.currentContext = 0;
  4818. EGL.currentReadSurface = 0;
  4819. EGL.currentDrawSurface = 0;
  4820. EGL.defaultDisplayInitialized = false;
  4821. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4822. return 1;
  4823. }
  4824. function _eglWaitClient() {
  4825. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4826. return 1;
  4827. }
  4828. var _eglWaitGL = _eglWaitClient;
  4829. function _eglWaitNative(nativeEngineId) {
  4830. EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
  4831. return 1;
  4832. }
  4833. var readAsmConstArgsArray = [];
  4834. function readAsmConstArgs(sigPtr, buf) {
  4835. // Nobody should have mutated _readAsmConstArgsArray underneath us to be something else than an array.
  4836. assert(Array.isArray(readAsmConstArgsArray));
  4837. // The input buffer is allocated on the stack, so it must be stack-aligned.
  4838. assert(buf % 16 == 0);
  4839. readAsmConstArgsArray.length = 0;
  4840. var ch;
  4841. // Most arguments are i32s, so shift the buffer pointer so it is a plain
  4842. // index into HEAP32.
  4843. buf >>= 2;
  4844. while (ch = HEAPU8[sigPtr++]) {
  4845. var chr = String.fromCharCode(ch);
  4846. var validChars = ['d', 'f', 'i'];
  4847. // In WASM_BIGINT mode we support passing i64 values as bigint.
  4848. validChars.push('j');
  4849. assert(validChars.includes(chr), 'Invalid character ' + ch + '("' + chr + '") in readAsmConstArgs! Use only [' + validChars + '], and do not specify "v" for void return argument.');
  4850. // Floats are always passed as doubles, and doubles and int64s take up 8
  4851. // bytes (two 32-bit slots) in memory, align reads to these:
  4852. buf += (ch != 105/*i*/) & buf;
  4853. readAsmConstArgsArray.push(
  4854. ch == 105/*i*/ ? HEAP32[buf] :
  4855. (ch == 106/*j*/ ? HEAP64 : HEAPF64)[buf++ >> 1]
  4856. );
  4857. ++buf;
  4858. }
  4859. return readAsmConstArgsArray;
  4860. }
  4861. function _emscripten_asm_const_int(code, sigPtr, argbuf) {
  4862. var args = readAsmConstArgs(sigPtr, argbuf);
  4863. if (!ASM_CONSTS.hasOwnProperty(code)) abort('No EM_ASM constant found at address ' + code);
  4864. return ASM_CONSTS[code].apply(null, args);
  4865. }
  4866. function mainThreadEM_ASM(code, sigPtr, argbuf, sync) {
  4867. var args = readAsmConstArgs(sigPtr, argbuf);
  4868. if (!ASM_CONSTS.hasOwnProperty(code)) abort('No EM_ASM constant found at address ' + code);
  4869. return ASM_CONSTS[code].apply(null, args);
  4870. }
  4871. function _emscripten_asm_const_int_sync_on_main_thread(code, sigPtr, argbuf) {
  4872. return mainThreadEM_ASM(code, sigPtr, argbuf, 1);
  4873. }
  4874. function _emscripten_cancel_main_loop() {
  4875. Browser.mainLoop.pause();
  4876. Browser.mainLoop.func = null;
  4877. }
  4878. function _emscripten_date_now() {
  4879. return Date.now();
  4880. }
  4881. var JSEvents = {inEventHandler:0,removeAllEventListeners:function() {
  4882. for (var i = JSEvents.eventHandlers.length-1; i >= 0; --i) {
  4883. JSEvents._removeHandler(i);
  4884. }
  4885. JSEvents.eventHandlers = [];
  4886. JSEvents.deferredCalls = [];
  4887. },registerRemoveEventListeners:function() {
  4888. if (!JSEvents.removeEventListenersRegistered) {
  4889. __ATEXIT__.push(JSEvents.removeAllEventListeners);
  4890. JSEvents.removeEventListenersRegistered = true;
  4891. }
  4892. },deferredCalls:[],deferCall:function(targetFunction, precedence, argsList) {
  4893. function arraysHaveEqualContent(arrA, arrB) {
  4894. if (arrA.length != arrB.length) return false;
  4895. for (var i in arrA) {
  4896. if (arrA[i] != arrB[i]) return false;
  4897. }
  4898. return true;
  4899. }
  4900. // Test if the given call was already queued, and if so, don't add it again.
  4901. for (var i in JSEvents.deferredCalls) {
  4902. var call = JSEvents.deferredCalls[i];
  4903. if (call.targetFunction == targetFunction && arraysHaveEqualContent(call.argsList, argsList)) {
  4904. return;
  4905. }
  4906. }
  4907. JSEvents.deferredCalls.push({
  4908. targetFunction: targetFunction,
  4909. precedence: precedence,
  4910. argsList: argsList
  4911. });
  4912. JSEvents.deferredCalls.sort(function(x,y) { return x.precedence < y.precedence; });
  4913. },removeDeferredCalls:function(targetFunction) {
  4914. for (var i = 0; i < JSEvents.deferredCalls.length; ++i) {
  4915. if (JSEvents.deferredCalls[i].targetFunction == targetFunction) {
  4916. JSEvents.deferredCalls.splice(i, 1);
  4917. --i;
  4918. }
  4919. }
  4920. },canPerformEventHandlerRequests:function() {
  4921. return JSEvents.inEventHandler && JSEvents.currentEventHandler.allowsDeferredCalls;
  4922. },runDeferredCalls:function() {
  4923. if (!JSEvents.canPerformEventHandlerRequests()) {
  4924. return;
  4925. }
  4926. for (var i = 0; i < JSEvents.deferredCalls.length; ++i) {
  4927. var call = JSEvents.deferredCalls[i];
  4928. JSEvents.deferredCalls.splice(i, 1);
  4929. --i;
  4930. call.targetFunction.apply(null, call.argsList);
  4931. }
  4932. },eventHandlers:[],removeAllHandlersOnTarget:function(target, eventTypeString) {
  4933. for (var i = 0; i < JSEvents.eventHandlers.length; ++i) {
  4934. if (JSEvents.eventHandlers[i].target == target &&
  4935. (!eventTypeString || eventTypeString == JSEvents.eventHandlers[i].eventTypeString)) {
  4936. JSEvents._removeHandler(i--);
  4937. }
  4938. }
  4939. },_removeHandler:function(i) {
  4940. var h = JSEvents.eventHandlers[i];
  4941. h.target.removeEventListener(h.eventTypeString, h.eventListenerFunc, h.useCapture);
  4942. JSEvents.eventHandlers.splice(i, 1);
  4943. },registerOrRemoveHandler:function(eventHandler) {
  4944. var jsEventHandler = function jsEventHandler(event) {
  4945. // Increment nesting count for the event handler.
  4946. ++JSEvents.inEventHandler;
  4947. JSEvents.currentEventHandler = eventHandler;
  4948. // Process any old deferred calls the user has placed.
  4949. JSEvents.runDeferredCalls();
  4950. // Process the actual event, calls back to user C code handler.
  4951. eventHandler.handlerFunc(event);
  4952. // Process any new deferred calls that were placed right now from this event handler.
  4953. JSEvents.runDeferredCalls();
  4954. // Out of event handler - restore nesting count.
  4955. --JSEvents.inEventHandler;
  4956. };
  4957. if (eventHandler.callbackfunc) {
  4958. eventHandler.eventListenerFunc = jsEventHandler;
  4959. eventHandler.target.addEventListener(eventHandler.eventTypeString, jsEventHandler, eventHandler.useCapture);
  4960. JSEvents.eventHandlers.push(eventHandler);
  4961. JSEvents.registerRemoveEventListeners();
  4962. } else {
  4963. for (var i = 0; i < JSEvents.eventHandlers.length; ++i) {
  4964. if (JSEvents.eventHandlers[i].target == eventHandler.target
  4965. && JSEvents.eventHandlers[i].eventTypeString == eventHandler.eventTypeString) {
  4966. JSEvents._removeHandler(i--);
  4967. }
  4968. }
  4969. }
  4970. },getNodeNameForTarget:function(target) {
  4971. if (!target) return '';
  4972. if (target == window) return '#window';
  4973. if (target == screen) return '#screen';
  4974. return (target && target.nodeName) ? target.nodeName : '';
  4975. },fullscreenEnabled:function() {
  4976. return document.fullscreenEnabled
  4977. // Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitFullscreenEnabled.
  4978. // TODO: If Safari at some point ships with unprefixed version, update the version check above.
  4979. || document.webkitFullscreenEnabled
  4980. ;
  4981. }};
  4982. var currentFullscreenStrategy = {};
  4983. function maybeCStringToJsString(cString) {
  4984. // "cString > 2" checks if the input is a number, and isn't of the special
  4985. // values we accept here, EMSCRIPTEN_EVENT_TARGET_* (which map to 0, 1, 2).
  4986. // In other words, if cString > 2 then it's a pointer to a valid place in
  4987. // memory, and points to a C string.
  4988. return cString > 2 ? UTF8ToString(cString) : cString;
  4989. }
  4990. var specialHTMLTargets = [0, typeof document != 'undefined' ? document : 0, typeof window != 'undefined' ? window : 0];
  4991. function findEventTarget(target) {
  4992. target = maybeCStringToJsString(target);
  4993. var domElement = specialHTMLTargets[target] || (typeof document != 'undefined' ? document.querySelector(target) : undefined);
  4994. return domElement;
  4995. }
  4996. function findCanvasEventTarget(target) { return findEventTarget(target); }
  4997. function _emscripten_get_canvas_element_size(target, width, height) {
  4998. var canvas = findCanvasEventTarget(target);
  4999. if (!canvas) return -4;
  5000. HEAP32[((width)>>2)] = canvas.width;
  5001. HEAP32[((height)>>2)] = canvas.height;
  5002. }
  5003. function getCanvasElementSize(target) {
  5004. return withStackSave(function() {
  5005. var w = stackAlloc(8);
  5006. var h = w + 4;
  5007. var targetInt = stackAlloc(target.id.length+1);
  5008. stringToUTF8(target.id, targetInt, target.id.length+1);
  5009. var ret = _emscripten_get_canvas_element_size(targetInt, w, h);
  5010. var size = [HEAP32[((w)>>2)], HEAP32[((h)>>2)]];
  5011. return size;
  5012. });
  5013. }
  5014. function _emscripten_set_canvas_element_size(target, width, height) {
  5015. var canvas = findCanvasEventTarget(target);
  5016. if (!canvas) return -4;
  5017. canvas.width = width;
  5018. canvas.height = height;
  5019. return 0;
  5020. }
  5021. function setCanvasElementSize(target, width, height) {
  5022. if (!target.controlTransferredOffscreen) {
  5023. target.width = width;
  5024. target.height = height;
  5025. } else {
  5026. // This function is being called from high-level JavaScript code instead of asm.js/Wasm,
  5027. // and it needs to synchronously proxy over to another thread, so marshal the string onto the heap to do the call.
  5028. withStackSave(function() {
  5029. var targetInt = stackAlloc(target.id.length+1);
  5030. stringToUTF8(target.id, targetInt, target.id.length+1);
  5031. _emscripten_set_canvas_element_size(targetInt, width, height);
  5032. });
  5033. }
  5034. }
  5035. function registerRestoreOldStyle(canvas) {
  5036. var canvasSize = getCanvasElementSize(canvas);
  5037. var oldWidth = canvasSize[0];
  5038. var oldHeight = canvasSize[1];
  5039. var oldCssWidth = canvas.style.width;
  5040. var oldCssHeight = canvas.style.height;
  5041. var oldBackgroundColor = canvas.style.backgroundColor; // Chrome reads color from here.
  5042. var oldDocumentBackgroundColor = document.body.style.backgroundColor; // IE11 reads color from here.
  5043. // Firefox always has black background color.
  5044. var oldPaddingLeft = canvas.style.paddingLeft; // Chrome, FF, Safari
  5045. var oldPaddingRight = canvas.style.paddingRight;
  5046. var oldPaddingTop = canvas.style.paddingTop;
  5047. var oldPaddingBottom = canvas.style.paddingBottom;
  5048. var oldMarginLeft = canvas.style.marginLeft; // IE11
  5049. var oldMarginRight = canvas.style.marginRight;
  5050. var oldMarginTop = canvas.style.marginTop;
  5051. var oldMarginBottom = canvas.style.marginBottom;
  5052. var oldDocumentBodyMargin = document.body.style.margin;
  5053. var oldDocumentOverflow = document.documentElement.style.overflow; // Chrome, Firefox
  5054. var oldDocumentScroll = document.body.scroll; // IE
  5055. var oldImageRendering = canvas.style.imageRendering;
  5056. function restoreOldStyle() {
  5057. var fullscreenElement = document.fullscreenElement
  5058. || document.webkitFullscreenElement
  5059. ;
  5060. if (!fullscreenElement) {
  5061. document.removeEventListener('fullscreenchange', restoreOldStyle);
  5062. // Unprefixed Fullscreen API shipped in Chromium 71 (https://bugs.chromium.org/p/chromium/issues/detail?id=383813)
  5063. // 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.
  5064. document.removeEventListener('webkitfullscreenchange', restoreOldStyle);
  5065. setCanvasElementSize(canvas, oldWidth, oldHeight);
  5066. canvas.style.width = oldCssWidth;
  5067. canvas.style.height = oldCssHeight;
  5068. canvas.style.backgroundColor = oldBackgroundColor; // Chrome
  5069. // IE11 hack: assigning 'undefined' or an empty string to document.body.style.backgroundColor has no effect, so first assign back the default color
  5070. // before setting the undefined value. Setting undefined value is also important, or otherwise we would later treat that as something that the user
  5071. // had explicitly set so subsequent fullscreen transitions would not set background color properly.
  5072. if (!oldDocumentBackgroundColor) document.body.style.backgroundColor = 'white';
  5073. document.body.style.backgroundColor = oldDocumentBackgroundColor; // IE11
  5074. canvas.style.paddingLeft = oldPaddingLeft; // Chrome, FF, Safari
  5075. canvas.style.paddingRight = oldPaddingRight;
  5076. canvas.style.paddingTop = oldPaddingTop;
  5077. canvas.style.paddingBottom = oldPaddingBottom;
  5078. canvas.style.marginLeft = oldMarginLeft; // IE11
  5079. canvas.style.marginRight = oldMarginRight;
  5080. canvas.style.marginTop = oldMarginTop;
  5081. canvas.style.marginBottom = oldMarginBottom;
  5082. document.body.style.margin = oldDocumentBodyMargin;
  5083. document.documentElement.style.overflow = oldDocumentOverflow; // Chrome, Firefox
  5084. document.body.scroll = oldDocumentScroll; // IE
  5085. canvas.style.imageRendering = oldImageRendering;
  5086. if (canvas.GLctxObject) canvas.GLctxObject.GLctx.viewport(0, 0, oldWidth, oldHeight);
  5087. if (currentFullscreenStrategy.canvasResizedCallback) {
  5088. ((a1, a2, a3) => dynCall_iiii.apply(null, [currentFullscreenStrategy.canvasResizedCallback, a1, a2, a3]))(37, 0, currentFullscreenStrategy.canvasResizedCallbackUserData);
  5089. }
  5090. }
  5091. }
  5092. document.addEventListener('fullscreenchange', restoreOldStyle);
  5093. // Unprefixed Fullscreen API shipped in Chromium 71 (https://bugs.chromium.org/p/chromium/issues/detail?id=383813)
  5094. // 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.
  5095. document.addEventListener('webkitfullscreenchange', restoreOldStyle);
  5096. return restoreOldStyle;
  5097. }
  5098. function setLetterbox(element, topBottom, leftRight) {
  5099. // Cannot use margin to specify letterboxes in FF or Chrome, since those ignore margins in fullscreen mode.
  5100. element.style.paddingLeft = element.style.paddingRight = leftRight + 'px';
  5101. element.style.paddingTop = element.style.paddingBottom = topBottom + 'px';
  5102. }
  5103. function getBoundingClientRect(e) {
  5104. return specialHTMLTargets.indexOf(e) < 0 ? e.getBoundingClientRect() : {'left':0,'top':0};
  5105. }
  5106. function JSEvents_resizeCanvasForFullscreen(target, strategy) {
  5107. var restoreOldStyle = registerRestoreOldStyle(target);
  5108. var cssWidth = strategy.softFullscreen ? innerWidth : screen.width;
  5109. var cssHeight = strategy.softFullscreen ? innerHeight : screen.height;
  5110. var rect = getBoundingClientRect(target);
  5111. var windowedCssWidth = rect.width;
  5112. var windowedCssHeight = rect.height;
  5113. var canvasSize = getCanvasElementSize(target);
  5114. var windowedRttWidth = canvasSize[0];
  5115. var windowedRttHeight = canvasSize[1];
  5116. if (strategy.scaleMode == 3) {
  5117. setLetterbox(target, (cssHeight - windowedCssHeight) / 2, (cssWidth - windowedCssWidth) / 2);
  5118. cssWidth = windowedCssWidth;
  5119. cssHeight = windowedCssHeight;
  5120. } else if (strategy.scaleMode == 2) {
  5121. if (cssWidth*windowedRttHeight < windowedRttWidth*cssHeight) {
  5122. var desiredCssHeight = windowedRttHeight * cssWidth / windowedRttWidth;
  5123. setLetterbox(target, (cssHeight - desiredCssHeight) / 2, 0);
  5124. cssHeight = desiredCssHeight;
  5125. } else {
  5126. var desiredCssWidth = windowedRttWidth * cssHeight / windowedRttHeight;
  5127. setLetterbox(target, 0, (cssWidth - desiredCssWidth) / 2);
  5128. cssWidth = desiredCssWidth;
  5129. }
  5130. }
  5131. // If we are adding padding, must choose a background color or otherwise Chrome will give the
  5132. // padding a default white color. Do it only if user has not customized their own background color.
  5133. if (!target.style.backgroundColor) target.style.backgroundColor = 'black';
  5134. // IE11 does the same, but requires the color to be set in the document body.
  5135. if (!document.body.style.backgroundColor) document.body.style.backgroundColor = 'black'; // IE11
  5136. // Firefox always shows black letterboxes independent of style color.
  5137. target.style.width = cssWidth + 'px';
  5138. target.style.height = cssHeight + 'px';
  5139. if (strategy.filteringMode == 1) {
  5140. target.style.imageRendering = 'optimizeSpeed';
  5141. target.style.imageRendering = '-moz-crisp-edges';
  5142. target.style.imageRendering = '-o-crisp-edges';
  5143. target.style.imageRendering = '-webkit-optimize-contrast';
  5144. target.style.imageRendering = 'optimize-contrast';
  5145. target.style.imageRendering = 'crisp-edges';
  5146. target.style.imageRendering = 'pixelated';
  5147. }
  5148. var dpiScale = (strategy.canvasResolutionScaleMode == 2) ? devicePixelRatio : 1;
  5149. if (strategy.canvasResolutionScaleMode != 0) {
  5150. var newWidth = (cssWidth * dpiScale)|0;
  5151. var newHeight = (cssHeight * dpiScale)|0;
  5152. setCanvasElementSize(target, newWidth, newHeight);
  5153. if (target.GLctxObject) target.GLctxObject.GLctx.viewport(0, 0, newWidth, newHeight);
  5154. }
  5155. return restoreOldStyle;
  5156. }
  5157. function JSEvents_requestFullscreen(target, strategy) {
  5158. // EMSCRIPTEN_FULLSCREEN_SCALE_DEFAULT + EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE is a mode where no extra logic is performed to the DOM elements.
  5159. if (strategy.scaleMode != 0 || strategy.canvasResolutionScaleMode != 0) {
  5160. JSEvents_resizeCanvasForFullscreen(target, strategy);
  5161. }
  5162. if (target.requestFullscreen) {
  5163. target.requestFullscreen();
  5164. } else if (target.webkitRequestFullscreen) {
  5165. target.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
  5166. } else {
  5167. return JSEvents.fullscreenEnabled() ? -3 : -1;
  5168. }
  5169. currentFullscreenStrategy = strategy;
  5170. if (strategy.canvasResizedCallback) {
  5171. ((a1, a2, a3) => dynCall_iiii.apply(null, [strategy.canvasResizedCallback, a1, a2, a3]))(37, 0, strategy.canvasResizedCallbackUserData);
  5172. }
  5173. return 0;
  5174. }
  5175. function _emscripten_exit_fullscreen() {
  5176. if (!JSEvents.fullscreenEnabled()) return -1;
  5177. // Make sure no queued up calls will fire after this.
  5178. JSEvents.removeDeferredCalls(JSEvents_requestFullscreen);
  5179. var d = specialHTMLTargets[1];
  5180. if (d.exitFullscreen) {
  5181. d.fullscreenElement && d.exitFullscreen();
  5182. } else if (d.webkitExitFullscreen) {
  5183. d.webkitFullscreenElement && d.webkitExitFullscreen();
  5184. } else {
  5185. return -1;
  5186. }
  5187. return 0;
  5188. }
  5189. function requestPointerLock(target) {
  5190. if (target.requestPointerLock) {
  5191. target.requestPointerLock();
  5192. } else {
  5193. // document.body is known to accept pointer lock, so use that to differentiate if the user passed a bad element,
  5194. // or if the whole browser just doesn't support the feature.
  5195. if (document.body.requestPointerLock
  5196. ) {
  5197. return -3;
  5198. }
  5199. return -1;
  5200. }
  5201. return 0;
  5202. }
  5203. function _emscripten_exit_pointerlock() {
  5204. // Make sure no queued up calls will fire after this.
  5205. JSEvents.removeDeferredCalls(requestPointerLock);
  5206. if (document.exitPointerLock) {
  5207. document.exitPointerLock();
  5208. } else {
  5209. return -1;
  5210. }
  5211. return 0;
  5212. }
  5213. function _emscripten_get_device_pixel_ratio() {
  5214. return (typeof devicePixelRatio == 'number' && devicePixelRatio) || 1.0;
  5215. }
  5216. function _emscripten_get_element_css_size(target, width, height) {
  5217. target = findEventTarget(target);
  5218. if (!target) return -4;
  5219. var rect = getBoundingClientRect(target);
  5220. HEAPF64[((width)>>3)] = rect.width;
  5221. HEAPF64[((height)>>3)] = rect.height;
  5222. return 0;
  5223. }
  5224. function fillGamepadEventData(eventStruct, e) {
  5225. HEAPF64[((eventStruct)>>3)] = e.timestamp;
  5226. for (var i = 0; i < e.axes.length; ++i) {
  5227. HEAPF64[(((eventStruct+i*8)+(16))>>3)] = e.axes[i];
  5228. }
  5229. for (var i = 0; i < e.buttons.length; ++i) {
  5230. if (typeof e.buttons[i] == 'object') {
  5231. HEAPF64[(((eventStruct+i*8)+(528))>>3)] = e.buttons[i].value;
  5232. } else {
  5233. HEAPF64[(((eventStruct+i*8)+(528))>>3)] = e.buttons[i];
  5234. }
  5235. }
  5236. for (var i = 0; i < e.buttons.length; ++i) {
  5237. if (typeof e.buttons[i] == 'object') {
  5238. HEAP32[(((eventStruct+i*4)+(1040))>>2)] = e.buttons[i].pressed;
  5239. } else {
  5240. // Assigning a boolean to HEAP32, that's ok, but Closure would like to warn about it:
  5241. /** @suppress {checkTypes} */
  5242. HEAP32[(((eventStruct+i*4)+(1040))>>2)] = e.buttons[i] == 1;
  5243. }
  5244. }
  5245. HEAP32[(((eventStruct)+(1296))>>2)] = e.connected;
  5246. HEAP32[(((eventStruct)+(1300))>>2)] = e.index;
  5247. HEAP32[(((eventStruct)+(8))>>2)] = e.axes.length;
  5248. HEAP32[(((eventStruct)+(12))>>2)] = e.buttons.length;
  5249. stringToUTF8(e.id, eventStruct + 1304, 64);
  5250. stringToUTF8(e.mapping, eventStruct + 1368, 64);
  5251. }
  5252. function _emscripten_get_gamepad_status(index, gamepadState) {
  5253. 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!';
  5254. // INVALID_PARAM is returned on a Gamepad index that never was there.
  5255. if (index < 0 || index >= JSEvents.lastGamepadState.length) return -5;
  5256. // NO_DATA is returned on a Gamepad index that was removed.
  5257. // For previously disconnected gamepads there should be an empty slot (null/undefined/false) at the index.
  5258. // This is because gamepads must keep their original position in the array.
  5259. // For example, removing the first of two gamepads produces [null/undefined/false, gamepad].
  5260. if (!JSEvents.lastGamepadState[index]) return -7;
  5261. fillGamepadEventData(gamepadState, JSEvents.lastGamepadState[index]);
  5262. return 0;
  5263. }
  5264. function _emscripten_get_num_gamepads() {
  5265. 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!';
  5266. // N.B. Do not call emscripten_get_num_gamepads() unless having first called emscripten_sample_gamepad_data(), and that has returned EMSCRIPTEN_RESULT_SUCCESS.
  5267. // Otherwise the following line will throw an exception.
  5268. return JSEvents.lastGamepadState.length;
  5269. }
  5270. function _emscripten_get_screen_size(width, height) {
  5271. HEAP32[((width)>>2)] = screen.width;
  5272. HEAP32[((height)>>2)] = screen.height;
  5273. }
  5274. function _emscripten_glActiveTexture(x0) { GLctx['activeTexture'](x0) }
  5275. function _emscripten_glAttachShader(program, shader) {
  5276. GLctx.attachShader(GL.programs[program], GL.shaders[shader]);
  5277. }
  5278. function _emscripten_glBeginQueryEXT(target, id) {
  5279. GLctx.disjointTimerQueryExt['beginQueryEXT'](target, GL.queries[id]);
  5280. }
  5281. function _emscripten_glBindAttribLocation(program, index, name) {
  5282. GLctx.bindAttribLocation(GL.programs[program], index, UTF8ToString(name));
  5283. }
  5284. function _emscripten_glBindBuffer(target, buffer) {
  5285. GLctx.bindBuffer(target, GL.buffers[buffer]);
  5286. }
  5287. function _emscripten_glBindFramebuffer(target, framebuffer) {
  5288. GLctx.bindFramebuffer(target, GL.framebuffers[framebuffer]);
  5289. }
  5290. function _emscripten_glBindRenderbuffer(target, renderbuffer) {
  5291. GLctx.bindRenderbuffer(target, GL.renderbuffers[renderbuffer]);
  5292. }
  5293. function _emscripten_glBindTexture(target, texture) {
  5294. GLctx.bindTexture(target, GL.textures[texture]);
  5295. }
  5296. function _emscripten_glBindVertexArrayOES(vao) {
  5297. GLctx['bindVertexArray'](GL.vaos[vao]);
  5298. }
  5299. function _emscripten_glBlendColor(x0, x1, x2, x3) { GLctx['blendColor'](x0, x1, x2, x3) }
  5300. function _emscripten_glBlendEquation(x0) { GLctx['blendEquation'](x0) }
  5301. function _emscripten_glBlendEquationSeparate(x0, x1) { GLctx['blendEquationSeparate'](x0, x1) }
  5302. function _emscripten_glBlendFunc(x0, x1) { GLctx['blendFunc'](x0, x1) }
  5303. function _emscripten_glBlendFuncSeparate(x0, x1, x2, x3) { GLctx['blendFuncSeparate'](x0, x1, x2, x3) }
  5304. function _emscripten_glBufferData(target, size, data, usage) {
  5305. // N.b. here first form specifies a heap subarray, second form an integer size, so the ?: code here is polymorphic. It is advised to avoid
  5306. // randomly mixing both uses in calling code, to avoid any potential JS engine JIT issues.
  5307. GLctx.bufferData(target, data ? HEAPU8.subarray(data, data+size) : size, usage);
  5308. }
  5309. function _emscripten_glBufferSubData(target, offset, size, data) {
  5310. GLctx.bufferSubData(target, offset, HEAPU8.subarray(data, data+size));
  5311. }
  5312. function _emscripten_glCheckFramebufferStatus(x0) { return GLctx['checkFramebufferStatus'](x0) }
  5313. function _emscripten_glClear(x0) { GLctx['clear'](x0) }
  5314. function _emscripten_glClearColor(x0, x1, x2, x3) { GLctx['clearColor'](x0, x1, x2, x3) }
  5315. function _emscripten_glClearDepthf(x0) { GLctx['clearDepth'](x0) }
  5316. function _emscripten_glClearStencil(x0) { GLctx['clearStencil'](x0) }
  5317. function _emscripten_glColorMask(red, green, blue, alpha) {
  5318. GLctx.colorMask(!!red, !!green, !!blue, !!alpha);
  5319. }
  5320. function _emscripten_glCompileShader(shader) {
  5321. GLctx.compileShader(GL.shaders[shader]);
  5322. }
  5323. function _emscripten_glCompressedTexImage2D(target, level, internalFormat, width, height, border, imageSize, data) {
  5324. GLctx['compressedTexImage2D'](target, level, internalFormat, width, height, border, data ? HEAPU8.subarray((data), (data+imageSize)) : null);
  5325. }
  5326. function _emscripten_glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data) {
  5327. GLctx['compressedTexSubImage2D'](target, level, xoffset, yoffset, width, height, format, data ? HEAPU8.subarray((data), (data+imageSize)) : null);
  5328. }
  5329. function _emscripten_glCopyTexImage2D(x0, x1, x2, x3, x4, x5, x6, x7) { GLctx['copyTexImage2D'](x0, x1, x2, x3, x4, x5, x6, x7) }
  5330. function _emscripten_glCopyTexSubImage2D(x0, x1, x2, x3, x4, x5, x6, x7) { GLctx['copyTexSubImage2D'](x0, x1, x2, x3, x4, x5, x6, x7) }
  5331. function _emscripten_glCreateProgram() {
  5332. var id = GL.getNewId(GL.programs);
  5333. var program = GLctx.createProgram();
  5334. // Store additional information needed for each shader program:
  5335. program.name = id;
  5336. // Lazy cache results of glGetProgramiv(GL_ACTIVE_UNIFORM_MAX_LENGTH/GL_ACTIVE_ATTRIBUTE_MAX_LENGTH/GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH)
  5337. program.maxUniformLength = program.maxAttributeLength = program.maxUniformBlockNameLength = 0;
  5338. program.uniformIdCounter = 1;
  5339. GL.programs[id] = program;
  5340. return id;
  5341. }
  5342. function _emscripten_glCreateShader(shaderType) {
  5343. var id = GL.getNewId(GL.shaders);
  5344. GL.shaders[id] = GLctx.createShader(shaderType);
  5345. return id;
  5346. }
  5347. function _emscripten_glCullFace(x0) { GLctx['cullFace'](x0) }
  5348. function _emscripten_glDeleteBuffers(n, buffers) {
  5349. for (var i = 0; i < n; i++) {
  5350. var id = HEAP32[(((buffers)+(i*4))>>2)];
  5351. var buffer = GL.buffers[id];
  5352. // From spec: "glDeleteBuffers silently ignores 0's and names that do not
  5353. // correspond to existing buffer objects."
  5354. if (!buffer) continue;
  5355. GLctx.deleteBuffer(buffer);
  5356. buffer.name = 0;
  5357. GL.buffers[id] = null;
  5358. }
  5359. }
  5360. function _emscripten_glDeleteFramebuffers(n, framebuffers) {
  5361. for (var i = 0; i < n; ++i) {
  5362. var id = HEAP32[(((framebuffers)+(i*4))>>2)];
  5363. var framebuffer = GL.framebuffers[id];
  5364. if (!framebuffer) continue; // GL spec: "glDeleteFramebuffers silently ignores 0s and names that do not correspond to existing framebuffer objects".
  5365. GLctx.deleteFramebuffer(framebuffer);
  5366. framebuffer.name = 0;
  5367. GL.framebuffers[id] = null;
  5368. }
  5369. }
  5370. function _emscripten_glDeleteProgram(id) {
  5371. if (!id) return;
  5372. var program = GL.programs[id];
  5373. if (!program) { // glDeleteProgram actually signals an error when deleting a nonexisting object, unlike some other GL delete functions.
  5374. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  5375. return;
  5376. }
  5377. GLctx.deleteProgram(program);
  5378. program.name = 0;
  5379. GL.programs[id] = null;
  5380. }
  5381. function _emscripten_glDeleteQueriesEXT(n, ids) {
  5382. for (var i = 0; i < n; i++) {
  5383. var id = HEAP32[(((ids)+(i*4))>>2)];
  5384. var query = GL.queries[id];
  5385. if (!query) continue; // GL spec: "unused names in ids are ignored, as is the name zero."
  5386. GLctx.disjointTimerQueryExt['deleteQueryEXT'](query);
  5387. GL.queries[id] = null;
  5388. }
  5389. }
  5390. function _emscripten_glDeleteRenderbuffers(n, renderbuffers) {
  5391. for (var i = 0; i < n; i++) {
  5392. var id = HEAP32[(((renderbuffers)+(i*4))>>2)];
  5393. var renderbuffer = GL.renderbuffers[id];
  5394. if (!renderbuffer) continue; // GL spec: "glDeleteRenderbuffers silently ignores 0s and names that do not correspond to existing renderbuffer objects".
  5395. GLctx.deleteRenderbuffer(renderbuffer);
  5396. renderbuffer.name = 0;
  5397. GL.renderbuffers[id] = null;
  5398. }
  5399. }
  5400. function _emscripten_glDeleteShader(id) {
  5401. if (!id) return;
  5402. var shader = GL.shaders[id];
  5403. if (!shader) { // glDeleteShader actually signals an error when deleting a nonexisting object, unlike some other GL delete functions.
  5404. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  5405. return;
  5406. }
  5407. GLctx.deleteShader(shader);
  5408. GL.shaders[id] = null;
  5409. }
  5410. function _emscripten_glDeleteTextures(n, textures) {
  5411. for (var i = 0; i < n; i++) {
  5412. var id = HEAP32[(((textures)+(i*4))>>2)];
  5413. var texture = GL.textures[id];
  5414. if (!texture) continue; // GL spec: "glDeleteTextures silently ignores 0s and names that do not correspond to existing textures".
  5415. GLctx.deleteTexture(texture);
  5416. texture.name = 0;
  5417. GL.textures[id] = null;
  5418. }
  5419. }
  5420. function _emscripten_glDeleteVertexArraysOES(n, vaos) {
  5421. for (var i = 0; i < n; i++) {
  5422. var id = HEAP32[(((vaos)+(i*4))>>2)];
  5423. GLctx['deleteVertexArray'](GL.vaos[id]);
  5424. GL.vaos[id] = null;
  5425. }
  5426. }
  5427. function _emscripten_glDepthFunc(x0) { GLctx['depthFunc'](x0) }
  5428. function _emscripten_glDepthMask(flag) {
  5429. GLctx.depthMask(!!flag);
  5430. }
  5431. function _emscripten_glDepthRangef(x0, x1) { GLctx['depthRange'](x0, x1) }
  5432. function _emscripten_glDetachShader(program, shader) {
  5433. GLctx.detachShader(GL.programs[program], GL.shaders[shader]);
  5434. }
  5435. function _emscripten_glDisable(x0) { GLctx['disable'](x0) }
  5436. function _emscripten_glDisableVertexAttribArray(index) {
  5437. GLctx.disableVertexAttribArray(index);
  5438. }
  5439. function _emscripten_glDrawArrays(mode, first, count) {
  5440. GLctx.drawArrays(mode, first, count);
  5441. }
  5442. function _emscripten_glDrawArraysInstancedANGLE(mode, first, count, primcount) {
  5443. GLctx['drawArraysInstanced'](mode, first, count, primcount);
  5444. }
  5445. var tempFixedLengthArray = [];
  5446. function _emscripten_glDrawBuffersWEBGL(n, bufs) {
  5447. var bufArray = tempFixedLengthArray[n];
  5448. for (var i = 0; i < n; i++) {
  5449. bufArray[i] = HEAP32[(((bufs)+(i*4))>>2)];
  5450. }
  5451. GLctx['drawBuffers'](bufArray);
  5452. }
  5453. function _emscripten_glDrawElements(mode, count, type, indices) {
  5454. GLctx.drawElements(mode, count, type, indices);
  5455. }
  5456. function _emscripten_glDrawElementsInstancedANGLE(mode, count, type, indices, primcount) {
  5457. GLctx['drawElementsInstanced'](mode, count, type, indices, primcount);
  5458. }
  5459. function _emscripten_glEnable(x0) { GLctx['enable'](x0) }
  5460. function _emscripten_glEnableVertexAttribArray(index) {
  5461. GLctx.enableVertexAttribArray(index);
  5462. }
  5463. function _emscripten_glEndQueryEXT(target) {
  5464. GLctx.disjointTimerQueryExt['endQueryEXT'](target);
  5465. }
  5466. function _emscripten_glFinish() { GLctx['finish']() }
  5467. function _emscripten_glFlush() { GLctx['flush']() }
  5468. function _emscripten_glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer) {
  5469. GLctx.framebufferRenderbuffer(target, attachment, renderbuffertarget,
  5470. GL.renderbuffers[renderbuffer]);
  5471. }
  5472. function _emscripten_glFramebufferTexture2D(target, attachment, textarget, texture, level) {
  5473. GLctx.framebufferTexture2D(target, attachment, textarget,
  5474. GL.textures[texture], level);
  5475. }
  5476. function _emscripten_glFrontFace(x0) { GLctx['frontFace'](x0) }
  5477. function __glGenObject(n, buffers, createFunction, objectTable
  5478. ) {
  5479. for (var i = 0; i < n; i++) {
  5480. var buffer = GLctx[createFunction]();
  5481. var id = buffer && GL.getNewId(objectTable);
  5482. if (buffer) {
  5483. buffer.name = id;
  5484. objectTable[id] = buffer;
  5485. } else {
  5486. GL.recordError(0x502 /* GL_INVALID_OPERATION */);
  5487. }
  5488. HEAP32[(((buffers)+(i*4))>>2)] = id;
  5489. }
  5490. }
  5491. function _emscripten_glGenBuffers(n, buffers) {
  5492. __glGenObject(n, buffers, 'createBuffer', GL.buffers
  5493. );
  5494. }
  5495. function _emscripten_glGenFramebuffers(n, ids) {
  5496. __glGenObject(n, ids, 'createFramebuffer', GL.framebuffers
  5497. );
  5498. }
  5499. function _emscripten_glGenQueriesEXT(n, ids) {
  5500. for (var i = 0; i < n; i++) {
  5501. var query = GLctx.disjointTimerQueryExt['createQueryEXT']();
  5502. if (!query) {
  5503. GL.recordError(0x502 /* GL_INVALID_OPERATION */);
  5504. while (i < n) HEAP32[(((ids)+(i++*4))>>2)] = 0;
  5505. return;
  5506. }
  5507. var id = GL.getNewId(GL.queries);
  5508. query.name = id;
  5509. GL.queries[id] = query;
  5510. HEAP32[(((ids)+(i*4))>>2)] = id;
  5511. }
  5512. }
  5513. function _emscripten_glGenRenderbuffers(n, renderbuffers) {
  5514. __glGenObject(n, renderbuffers, 'createRenderbuffer', GL.renderbuffers
  5515. );
  5516. }
  5517. function _emscripten_glGenTextures(n, textures) {
  5518. __glGenObject(n, textures, 'createTexture', GL.textures
  5519. );
  5520. }
  5521. function _emscripten_glGenVertexArraysOES(n, arrays) {
  5522. __glGenObject(n, arrays, 'createVertexArray', GL.vaos
  5523. );
  5524. }
  5525. function _emscripten_glGenerateMipmap(x0) { GLctx['generateMipmap'](x0) }
  5526. function __glGetActiveAttribOrUniform(funcName, program, index, bufSize, length, size, type, name) {
  5527. program = GL.programs[program];
  5528. var info = GLctx[funcName](program, index);
  5529. if (info) { // If an error occurs, nothing will be written to length, size and type and name.
  5530. var numBytesWrittenExclNull = name && stringToUTF8(info.name, name, bufSize);
  5531. if (length) HEAP32[((length)>>2)] = numBytesWrittenExclNull;
  5532. if (size) HEAP32[((size)>>2)] = info.size;
  5533. if (type) HEAP32[((type)>>2)] = info.type;
  5534. }
  5535. }
  5536. function _emscripten_glGetActiveAttrib(program, index, bufSize, length, size, type, name) {
  5537. __glGetActiveAttribOrUniform('getActiveAttrib', program, index, bufSize, length, size, type, name);
  5538. }
  5539. function _emscripten_glGetActiveUniform(program, index, bufSize, length, size, type, name) {
  5540. __glGetActiveAttribOrUniform('getActiveUniform', program, index, bufSize, length, size, type, name);
  5541. }
  5542. function _emscripten_glGetAttachedShaders(program, maxCount, count, shaders) {
  5543. var result = GLctx.getAttachedShaders(GL.programs[program]);
  5544. var len = result.length;
  5545. if (len > maxCount) {
  5546. len = maxCount;
  5547. }
  5548. HEAP32[((count)>>2)] = len;
  5549. for (var i = 0; i < len; ++i) {
  5550. var id = GL.shaders.indexOf(result[i]);
  5551. HEAP32[(((shaders)+(i*4))>>2)] = id;
  5552. }
  5553. }
  5554. function _emscripten_glGetAttribLocation(program, name) {
  5555. return GLctx.getAttribLocation(GL.programs[program], UTF8ToString(name));
  5556. }
  5557. function readI53FromI64(ptr) {
  5558. return HEAPU32[ptr>>2] + HEAP32[ptr+4>>2] * 4294967296;
  5559. }
  5560. function readI53FromU64(ptr) {
  5561. return HEAPU32[ptr>>2] + HEAPU32[ptr+4>>2] * 4294967296;
  5562. }
  5563. function writeI53ToI64(ptr, num) {
  5564. HEAPU32[ptr>>2] = num;
  5565. HEAPU32[ptr+4>>2] = (num - HEAPU32[ptr>>2])/4294967296;
  5566. var deserialized = (num >= 0) ? readI53FromU64(ptr) : readI53FromI64(ptr);
  5567. if (deserialized != num) warnOnce('writeI53ToI64() out of range: serialized JS Number ' + num + ' to Wasm heap as bytes lo=' + ptrToString(HEAPU32[ptr>>2]) + ', hi=' + ptrToString(HEAPU32[ptr+4>>2]) + ', which deserializes back to ' + deserialized + ' instead!');
  5568. }
  5569. function emscriptenWebGLGet(name_, p, type) {
  5570. // Guard against user passing a null pointer.
  5571. // Note that GLES2 spec does not say anything about how passing a null pointer should be treated.
  5572. // Testing on desktop core GL 3, the application crashes on glGetIntegerv to a null pointer, but
  5573. // better to report an error instead of doing anything random.
  5574. if (!p) {
  5575. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  5576. return;
  5577. }
  5578. var ret = undefined;
  5579. switch (name_) { // Handle a few trivial GLES values
  5580. case 0x8DFA: // GL_SHADER_COMPILER
  5581. ret = 1;
  5582. break;
  5583. case 0x8DF8: // GL_SHADER_BINARY_FORMATS
  5584. if (type != 0 && type != 1) {
  5585. GL.recordError(0x500); // GL_INVALID_ENUM
  5586. }
  5587. return; // Do not write anything to the out pointer, since no binary formats are supported.
  5588. case 0x8DF9: // GL_NUM_SHADER_BINARY_FORMATS
  5589. ret = 0;
  5590. break;
  5591. case 0x86A2: // GL_NUM_COMPRESSED_TEXTURE_FORMATS
  5592. // WebGL doesn't have GL_NUM_COMPRESSED_TEXTURE_FORMATS (it's obsolete since GL_COMPRESSED_TEXTURE_FORMATS returns a JS array that can be queried for length),
  5593. // so implement it ourselves to allow C++ GLES2 code get the length.
  5594. var formats = GLctx.getParameter(0x86A3 /*GL_COMPRESSED_TEXTURE_FORMATS*/);
  5595. ret = formats ? formats.length : 0;
  5596. break;
  5597. }
  5598. if (ret === undefined) {
  5599. var result = GLctx.getParameter(name_);
  5600. switch (typeof result) {
  5601. case "number":
  5602. ret = result;
  5603. break;
  5604. case "boolean":
  5605. ret = result ? 1 : 0;
  5606. break;
  5607. case "string":
  5608. GL.recordError(0x500); // GL_INVALID_ENUM
  5609. return;
  5610. case "object":
  5611. if (result === null) {
  5612. // null is a valid result for some (e.g., which buffer is bound - perhaps nothing is bound), but otherwise
  5613. // can mean an invalid name_, which we need to report as an error
  5614. switch (name_) {
  5615. case 0x8894: // ARRAY_BUFFER_BINDING
  5616. case 0x8B8D: // CURRENT_PROGRAM
  5617. case 0x8895: // ELEMENT_ARRAY_BUFFER_BINDING
  5618. case 0x8CA6: // FRAMEBUFFER_BINDING or DRAW_FRAMEBUFFER_BINDING
  5619. case 0x8CA7: // RENDERBUFFER_BINDING
  5620. case 0x8069: // TEXTURE_BINDING_2D
  5621. case 0x85B5: // WebGL 2 GL_VERTEX_ARRAY_BINDING, or WebGL 1 extension OES_vertex_array_object GL_VERTEX_ARRAY_BINDING_OES
  5622. case 0x8514: { // TEXTURE_BINDING_CUBE_MAP
  5623. ret = 0;
  5624. break;
  5625. }
  5626. default: {
  5627. GL.recordError(0x500); // GL_INVALID_ENUM
  5628. return;
  5629. }
  5630. }
  5631. } else if (result instanceof Float32Array ||
  5632. result instanceof Uint32Array ||
  5633. result instanceof Int32Array ||
  5634. result instanceof Array) {
  5635. for (var i = 0; i < result.length; ++i) {
  5636. switch (type) {
  5637. case 0: HEAP32[(((p)+(i*4))>>2)] = result[i]; break;
  5638. case 2: HEAPF32[(((p)+(i*4))>>2)] = result[i]; break;
  5639. case 4: HEAP8[(((p)+(i))>>0)] = result[i] ? 1 : 0; break;
  5640. }
  5641. }
  5642. return;
  5643. } else {
  5644. try {
  5645. ret = result.name | 0;
  5646. } catch(e) {
  5647. GL.recordError(0x500); // GL_INVALID_ENUM
  5648. err('GL_INVALID_ENUM in glGet' + type + 'v: Unknown object returned from WebGL getParameter(' + name_ + ')! (error: ' + e + ')');
  5649. return;
  5650. }
  5651. }
  5652. break;
  5653. default:
  5654. GL.recordError(0x500); // GL_INVALID_ENUM
  5655. err('GL_INVALID_ENUM in glGet' + type + 'v: Native code calling glGet' + type + 'v(' + name_ + ') and it returns ' + result + ' of type ' + typeof(result) + '!');
  5656. return;
  5657. }
  5658. }
  5659. switch (type) {
  5660. case 1: writeI53ToI64(p, ret); break;
  5661. case 0: HEAP32[((p)>>2)] = ret; break;
  5662. case 2: HEAPF32[((p)>>2)] = ret; break;
  5663. case 4: HEAP8[((p)>>0)] = ret ? 1 : 0; break;
  5664. }
  5665. }
  5666. function _emscripten_glGetBooleanv(name_, p) {
  5667. emscriptenWebGLGet(name_, p, 4);
  5668. }
  5669. function _emscripten_glGetBufferParameteriv(target, value, data) {
  5670. if (!data) {
  5671. // GLES2 specification does not specify how to behave if data is a null pointer. Since calling this function does not make sense
  5672. // if data == null, issue a GL error to notify user about it.
  5673. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  5674. return;
  5675. }
  5676. HEAP32[((data)>>2)] = GLctx.getBufferParameter(target, value);
  5677. }
  5678. function _emscripten_glGetError() {
  5679. var error = GLctx.getError() || GL.lastError;
  5680. GL.lastError = 0/*GL_NO_ERROR*/;
  5681. return error;
  5682. }
  5683. function _emscripten_glGetFloatv(name_, p) {
  5684. emscriptenWebGLGet(name_, p, 2);
  5685. }
  5686. function _emscripten_glGetFramebufferAttachmentParameteriv(target, attachment, pname, params) {
  5687. var result = GLctx.getFramebufferAttachmentParameter(target, attachment, pname);
  5688. if (result instanceof WebGLRenderbuffer ||
  5689. result instanceof WebGLTexture) {
  5690. result = result.name | 0;
  5691. }
  5692. HEAP32[((params)>>2)] = result;
  5693. }
  5694. function _emscripten_glGetIntegerv(name_, p) {
  5695. emscriptenWebGLGet(name_, p, 0);
  5696. }
  5697. function _emscripten_glGetProgramInfoLog(program, maxLength, length, infoLog) {
  5698. var log = GLctx.getProgramInfoLog(GL.programs[program]);
  5699. if (log === null) log = '(unknown error)';
  5700. var numBytesWrittenExclNull = (maxLength > 0 && infoLog) ? stringToUTF8(log, infoLog, maxLength) : 0;
  5701. if (length) HEAP32[((length)>>2)] = numBytesWrittenExclNull;
  5702. }
  5703. function _emscripten_glGetProgramiv(program, pname, p) {
  5704. if (!p) {
  5705. // GLES2 specification does not specify how to behave if p is a null pointer. Since calling this function does not make sense
  5706. // if p == null, issue a GL error to notify user about it.
  5707. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  5708. return;
  5709. }
  5710. if (program >= GL.counter) {
  5711. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  5712. return;
  5713. }
  5714. program = GL.programs[program];
  5715. if (pname == 0x8B84) { // GL_INFO_LOG_LENGTH
  5716. var log = GLctx.getProgramInfoLog(program);
  5717. if (log === null) log = '(unknown error)';
  5718. HEAP32[((p)>>2)] = log.length + 1;
  5719. } else if (pname == 0x8B87 /* GL_ACTIVE_UNIFORM_MAX_LENGTH */) {
  5720. if (!program.maxUniformLength) {
  5721. for (var i = 0; i < GLctx.getProgramParameter(program, 0x8B86/*GL_ACTIVE_UNIFORMS*/); ++i) {
  5722. program.maxUniformLength = Math.max(program.maxUniformLength, GLctx.getActiveUniform(program, i).name.length+1);
  5723. }
  5724. }
  5725. HEAP32[((p)>>2)] = program.maxUniformLength;
  5726. } else if (pname == 0x8B8A /* GL_ACTIVE_ATTRIBUTE_MAX_LENGTH */) {
  5727. if (!program.maxAttributeLength) {
  5728. for (var i = 0; i < GLctx.getProgramParameter(program, 0x8B89/*GL_ACTIVE_ATTRIBUTES*/); ++i) {
  5729. program.maxAttributeLength = Math.max(program.maxAttributeLength, GLctx.getActiveAttrib(program, i).name.length+1);
  5730. }
  5731. }
  5732. HEAP32[((p)>>2)] = program.maxAttributeLength;
  5733. } else if (pname == 0x8A35 /* GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH */) {
  5734. if (!program.maxUniformBlockNameLength) {
  5735. for (var i = 0; i < GLctx.getProgramParameter(program, 0x8A36/*GL_ACTIVE_UNIFORM_BLOCKS*/); ++i) {
  5736. program.maxUniformBlockNameLength = Math.max(program.maxUniformBlockNameLength, GLctx.getActiveUniformBlockName(program, i).length+1);
  5737. }
  5738. }
  5739. HEAP32[((p)>>2)] = program.maxUniformBlockNameLength;
  5740. } else {
  5741. HEAP32[((p)>>2)] = GLctx.getProgramParameter(program, pname);
  5742. }
  5743. }
  5744. function _emscripten_glGetQueryObjecti64vEXT(id, pname, params) {
  5745. if (!params) {
  5746. // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
  5747. // if p == null, issue a GL error to notify user about it.
  5748. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  5749. return;
  5750. }
  5751. var query = GL.queries[id];
  5752. var param;
  5753. {
  5754. param = GLctx.disjointTimerQueryExt['getQueryObjectEXT'](query, pname);
  5755. }
  5756. var ret;
  5757. if (typeof param == 'boolean') {
  5758. ret = param ? 1 : 0;
  5759. } else {
  5760. ret = param;
  5761. }
  5762. writeI53ToI64(params, ret);
  5763. }
  5764. function _emscripten_glGetQueryObjectivEXT(id, pname, params) {
  5765. if (!params) {
  5766. // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
  5767. // if p == null, issue a GL error to notify user about it.
  5768. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  5769. return;
  5770. }
  5771. var query = GL.queries[id];
  5772. var param = GLctx.disjointTimerQueryExt['getQueryObjectEXT'](query, pname);
  5773. var ret;
  5774. if (typeof param == 'boolean') {
  5775. ret = param ? 1 : 0;
  5776. } else {
  5777. ret = param;
  5778. }
  5779. HEAP32[((params)>>2)] = ret;
  5780. }
  5781. function _emscripten_glGetQueryObjectui64vEXT(id, pname, params) {
  5782. if (!params) {
  5783. // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
  5784. // if p == null, issue a GL error to notify user about it.
  5785. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  5786. return;
  5787. }
  5788. var query = GL.queries[id];
  5789. var param;
  5790. {
  5791. param = GLctx.disjointTimerQueryExt['getQueryObjectEXT'](query, pname);
  5792. }
  5793. var ret;
  5794. if (typeof param == 'boolean') {
  5795. ret = param ? 1 : 0;
  5796. } else {
  5797. ret = param;
  5798. }
  5799. writeI53ToI64(params, ret);
  5800. }
  5801. function _emscripten_glGetQueryObjectuivEXT(id, pname, params) {
  5802. if (!params) {
  5803. // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
  5804. // if p == null, issue a GL error to notify user about it.
  5805. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  5806. return;
  5807. }
  5808. var query = GL.queries[id];
  5809. var param = GLctx.disjointTimerQueryExt['getQueryObjectEXT'](query, pname);
  5810. var ret;
  5811. if (typeof param == 'boolean') {
  5812. ret = param ? 1 : 0;
  5813. } else {
  5814. ret = param;
  5815. }
  5816. HEAP32[((params)>>2)] = ret;
  5817. }
  5818. function _emscripten_glGetQueryivEXT(target, pname, params) {
  5819. if (!params) {
  5820. // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
  5821. // if p == null, issue a GL error to notify user about it.
  5822. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  5823. return;
  5824. }
  5825. HEAP32[((params)>>2)] = GLctx.disjointTimerQueryExt['getQueryEXT'](target, pname);
  5826. }
  5827. function _emscripten_glGetRenderbufferParameteriv(target, pname, params) {
  5828. if (!params) {
  5829. // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
  5830. // if params == null, issue a GL error to notify user about it.
  5831. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  5832. return;
  5833. }
  5834. HEAP32[((params)>>2)] = GLctx.getRenderbufferParameter(target, pname);
  5835. }
  5836. function _emscripten_glGetShaderInfoLog(shader, maxLength, length, infoLog) {
  5837. var log = GLctx.getShaderInfoLog(GL.shaders[shader]);
  5838. if (log === null) log = '(unknown error)';
  5839. var numBytesWrittenExclNull = (maxLength > 0 && infoLog) ? stringToUTF8(log, infoLog, maxLength) : 0;
  5840. if (length) HEAP32[((length)>>2)] = numBytesWrittenExclNull;
  5841. }
  5842. function _emscripten_glGetShaderPrecisionFormat(shaderType, precisionType, range, precision) {
  5843. var result = GLctx.getShaderPrecisionFormat(shaderType, precisionType);
  5844. HEAP32[((range)>>2)] = result.rangeMin;
  5845. HEAP32[(((range)+(4))>>2)] = result.rangeMax;
  5846. HEAP32[((precision)>>2)] = result.precision;
  5847. }
  5848. function _emscripten_glGetShaderSource(shader, bufSize, length, source) {
  5849. var result = GLctx.getShaderSource(GL.shaders[shader]);
  5850. if (!result) return; // If an error occurs, nothing will be written to length or source.
  5851. var numBytesWrittenExclNull = (bufSize > 0 && source) ? stringToUTF8(result, source, bufSize) : 0;
  5852. if (length) HEAP32[((length)>>2)] = numBytesWrittenExclNull;
  5853. }
  5854. function _emscripten_glGetShaderiv(shader, pname, p) {
  5855. if (!p) {
  5856. // GLES2 specification does not specify how to behave if p is a null pointer. Since calling this function does not make sense
  5857. // if p == null, issue a GL error to notify user about it.
  5858. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  5859. return;
  5860. }
  5861. if (pname == 0x8B84) { // GL_INFO_LOG_LENGTH
  5862. var log = GLctx.getShaderInfoLog(GL.shaders[shader]);
  5863. if (log === null) log = '(unknown error)';
  5864. // The GLES2 specification says that if the shader has an empty info log,
  5865. // a value of 0 is returned. Otherwise the log has a null char appended.
  5866. // (An empty string is falsey, so we can just check that instead of
  5867. // looking at log.length.)
  5868. var logLength = log ? log.length + 1 : 0;
  5869. HEAP32[((p)>>2)] = logLength;
  5870. } else if (pname == 0x8B88) { // GL_SHADER_SOURCE_LENGTH
  5871. var source = GLctx.getShaderSource(GL.shaders[shader]);
  5872. // source may be a null, or the empty string, both of which are falsey
  5873. // values that we report a 0 length for.
  5874. var sourceLength = source ? source.length + 1 : 0;
  5875. HEAP32[((p)>>2)] = sourceLength;
  5876. } else {
  5877. HEAP32[((p)>>2)] = GLctx.getShaderParameter(GL.shaders[shader], pname);
  5878. }
  5879. }
  5880. function stringToNewUTF8(jsString) {
  5881. var length = lengthBytesUTF8(jsString)+1;
  5882. var cString = _malloc(length);
  5883. stringToUTF8(jsString, cString, length);
  5884. return cString;
  5885. }
  5886. function _emscripten_glGetString(name_) {
  5887. var ret = GL.stringCache[name_];
  5888. if (!ret) {
  5889. switch (name_) {
  5890. case 0x1F03 /* GL_EXTENSIONS */:
  5891. var exts = GLctx.getSupportedExtensions() || []; // .getSupportedExtensions() can return null if context is lost, so coerce to empty array.
  5892. exts = exts.concat(exts.map(function(e) { return "GL_" + e; }));
  5893. ret = stringToNewUTF8(exts.join(' '));
  5894. break;
  5895. case 0x1F00 /* GL_VENDOR */:
  5896. case 0x1F01 /* GL_RENDERER */:
  5897. case 0x9245 /* UNMASKED_VENDOR_WEBGL */:
  5898. case 0x9246 /* UNMASKED_RENDERER_WEBGL */:
  5899. var s = GLctx.getParameter(name_);
  5900. if (!s) {
  5901. GL.recordError(0x500/*GL_INVALID_ENUM*/);
  5902. }
  5903. ret = s && stringToNewUTF8(s);
  5904. break;
  5905. case 0x1F02 /* GL_VERSION */:
  5906. var glVersion = GLctx.getParameter(0x1F02 /*GL_VERSION*/);
  5907. // return GLES version string corresponding to the version of the WebGL context
  5908. {
  5909. glVersion = 'OpenGL ES 2.0 (' + glVersion + ')';
  5910. }
  5911. ret = stringToNewUTF8(glVersion);
  5912. break;
  5913. case 0x8B8C /* GL_SHADING_LANGUAGE_VERSION */:
  5914. var glslVersion = GLctx.getParameter(0x8B8C /*GL_SHADING_LANGUAGE_VERSION*/);
  5915. // extract the version number 'N.M' from the string 'WebGL GLSL ES N.M ...'
  5916. var ver_re = /^WebGL GLSL ES ([0-9]\.[0-9][0-9]?)(?:$| .*)/;
  5917. var ver_num = glslVersion.match(ver_re);
  5918. if (ver_num !== null) {
  5919. if (ver_num[1].length == 3) ver_num[1] = ver_num[1] + '0'; // ensure minor version has 2 digits
  5920. glslVersion = 'OpenGL ES GLSL ES ' + ver_num[1] + ' (' + glslVersion + ')';
  5921. }
  5922. ret = stringToNewUTF8(glslVersion);
  5923. break;
  5924. default:
  5925. GL.recordError(0x500/*GL_INVALID_ENUM*/);
  5926. // fall through
  5927. }
  5928. GL.stringCache[name_] = ret;
  5929. }
  5930. return ret;
  5931. }
  5932. function _emscripten_glGetTexParameterfv(target, pname, params) {
  5933. if (!params) {
  5934. // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
  5935. // if p == null, issue a GL error to notify user about it.
  5936. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  5937. return;
  5938. }
  5939. HEAPF32[((params)>>2)] = GLctx.getTexParameter(target, pname);
  5940. }
  5941. function _emscripten_glGetTexParameteriv(target, pname, params) {
  5942. if (!params) {
  5943. // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
  5944. // if p == null, issue a GL error to notify user about it.
  5945. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  5946. return;
  5947. }
  5948. HEAP32[((params)>>2)] = GLctx.getTexParameter(target, pname);
  5949. }
  5950. /** @suppress {checkTypes} */
  5951. function jstoi_q(str) {
  5952. return parseInt(str);
  5953. }
  5954. /** @noinline */
  5955. function webglGetLeftBracePos(name) {
  5956. return name.slice(-1) == ']' && name.lastIndexOf('[');
  5957. }
  5958. function webglPrepareUniformLocationsBeforeFirstUse(program) {
  5959. var uniformLocsById = program.uniformLocsById, // Maps GLuint -> WebGLUniformLocation
  5960. uniformSizeAndIdsByName = program.uniformSizeAndIdsByName, // Maps name -> [uniform array length, GLuint]
  5961. i, j;
  5962. // On the first time invocation of glGetUniformLocation on this shader program:
  5963. // initialize cache data structures and discover which uniforms are arrays.
  5964. if (!uniformLocsById) {
  5965. // maps GLint integer locations to WebGLUniformLocations
  5966. program.uniformLocsById = uniformLocsById = {};
  5967. // maps integer locations back to uniform name strings, so that we can lazily fetch uniform array locations
  5968. program.uniformArrayNamesById = {};
  5969. for (i = 0; i < GLctx.getProgramParameter(program, 0x8B86/*GL_ACTIVE_UNIFORMS*/); ++i) {
  5970. var u = GLctx.getActiveUniform(program, i);
  5971. var nm = u.name;
  5972. var sz = u.size;
  5973. var lb = webglGetLeftBracePos(nm);
  5974. var arrayName = lb > 0 ? nm.slice(0, lb) : nm;
  5975. // Assign a new location.
  5976. var id = program.uniformIdCounter;
  5977. program.uniformIdCounter += sz;
  5978. // Eagerly get the location of the uniformArray[0] base element.
  5979. // The remaining indices >0 will be left for lazy evaluation to
  5980. // improve performance. Those may never be needed to fetch, if the
  5981. // application fills arrays always in full starting from the first
  5982. // element of the array.
  5983. uniformSizeAndIdsByName[arrayName] = [sz, id];
  5984. // Store placeholder integers in place that highlight that these
  5985. // >0 index locations are array indices pending population.
  5986. for(j = 0; j < sz; ++j) {
  5987. uniformLocsById[id] = j;
  5988. program.uniformArrayNamesById[id++] = arrayName;
  5989. }
  5990. }
  5991. }
  5992. }
  5993. function _emscripten_glGetUniformLocation(program, name) {
  5994. name = UTF8ToString(name);
  5995. if (program = GL.programs[program]) {
  5996. webglPrepareUniformLocationsBeforeFirstUse(program);
  5997. var uniformLocsById = program.uniformLocsById; // Maps GLuint -> WebGLUniformLocation
  5998. var arrayIndex = 0;
  5999. var uniformBaseName = name;
  6000. // Invariant: when populating integer IDs for uniform locations, we must maintain the precondition that
  6001. // arrays reside in contiguous addresses, i.e. for a 'vec4 colors[10];', colors[4] must be at location colors[0]+4.
  6002. // However, user might call glGetUniformLocation(program, "colors") for an array, so we cannot discover based on the user
  6003. // input arguments whether the uniform we are dealing with is an array. The only way to discover which uniforms are arrays
  6004. // is to enumerate over all the active uniforms in the program.
  6005. var leftBrace = webglGetLeftBracePos(name);
  6006. // If user passed an array accessor "[index]", parse the array index off the accessor.
  6007. if (leftBrace > 0) {
  6008. 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.
  6009. uniformBaseName = name.slice(0, leftBrace);
  6010. }
  6011. // Have we cached the location of this uniform before?
  6012. var sizeAndId = program.uniformSizeAndIdsByName[uniformBaseName]; // A pair [array length, GLint of the uniform location]
  6013. // If an uniform with this name exists, and if its index is within the array limits (if it's even an array),
  6014. // query the WebGLlocation, or return an existing cached location.
  6015. if (sizeAndId && arrayIndex < sizeAndId[0]) {
  6016. arrayIndex += sizeAndId[1]; // Add the base location of the uniform to the array index offset.
  6017. if ((uniformLocsById[arrayIndex] = uniformLocsById[arrayIndex] || GLctx.getUniformLocation(program, name))) {
  6018. return arrayIndex;
  6019. }
  6020. }
  6021. }
  6022. else {
  6023. // N.b. we are currently unable to distinguish between GL program IDs that never existed vs GL program IDs that have been deleted,
  6024. // so report GL_INVALID_VALUE in both cases.
  6025. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6026. }
  6027. return -1;
  6028. }
  6029. function webglGetUniformLocation(location) {
  6030. var p = GLctx.currentProgram;
  6031. if (p) {
  6032. var webglLoc = p.uniformLocsById[location];
  6033. // p.uniformLocsById[location] stores either an integer, or a WebGLUniformLocation.
  6034. // If an integer, we have not yet bound the location, so do it now. The integer value specifies the array index
  6035. // we should bind to.
  6036. if (typeof webglLoc == 'number') {
  6037. p.uniformLocsById[location] = webglLoc = GLctx.getUniformLocation(p, p.uniformArrayNamesById[location] + (webglLoc > 0 ? '[' + webglLoc + ']' : ''));
  6038. }
  6039. // Else an already cached WebGLUniformLocation, return it.
  6040. return webglLoc;
  6041. } else {
  6042. GL.recordError(0x502/*GL_INVALID_OPERATION*/);
  6043. }
  6044. }
  6045. /** @suppress{checkTypes} */
  6046. function emscriptenWebGLGetUniform(program, location, params, type) {
  6047. if (!params) {
  6048. // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
  6049. // if params == null, issue a GL error to notify user about it.
  6050. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6051. return;
  6052. }
  6053. program = GL.programs[program];
  6054. webglPrepareUniformLocationsBeforeFirstUse(program);
  6055. var data = GLctx.getUniform(program, webglGetUniformLocation(location));
  6056. if (typeof data == 'number' || typeof data == 'boolean') {
  6057. switch (type) {
  6058. case 0: HEAP32[((params)>>2)] = data; break;
  6059. case 2: HEAPF32[((params)>>2)] = data; break;
  6060. }
  6061. } else {
  6062. for (var i = 0; i < data.length; i++) {
  6063. switch (type) {
  6064. case 0: HEAP32[(((params)+(i*4))>>2)] = data[i]; break;
  6065. case 2: HEAPF32[(((params)+(i*4))>>2)] = data[i]; break;
  6066. }
  6067. }
  6068. }
  6069. }
  6070. function _emscripten_glGetUniformfv(program, location, params) {
  6071. emscriptenWebGLGetUniform(program, location, params, 2);
  6072. }
  6073. function _emscripten_glGetUniformiv(program, location, params) {
  6074. emscriptenWebGLGetUniform(program, location, params, 0);
  6075. }
  6076. function _emscripten_glGetVertexAttribPointerv(index, pname, pointer) {
  6077. if (!pointer) {
  6078. // GLES2 specification does not specify how to behave if pointer is a null pointer. Since calling this function does not make sense
  6079. // if pointer == null, issue a GL error to notify user about it.
  6080. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6081. return;
  6082. }
  6083. HEAP32[((pointer)>>2)] = GLctx.getVertexAttribOffset(index, pname);
  6084. }
  6085. /** @suppress{checkTypes} */
  6086. function emscriptenWebGLGetVertexAttrib(index, pname, params, type) {
  6087. if (!params) {
  6088. // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
  6089. // if params == null, issue a GL error to notify user about it.
  6090. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  6091. return;
  6092. }
  6093. var data = GLctx.getVertexAttrib(index, pname);
  6094. if (pname == 0x889F/*VERTEX_ATTRIB_ARRAY_BUFFER_BINDING*/) {
  6095. HEAP32[((params)>>2)] = data && data["name"];
  6096. } else if (typeof data == 'number' || typeof data == 'boolean') {
  6097. switch (type) {
  6098. case 0: HEAP32[((params)>>2)] = data; break;
  6099. case 2: HEAPF32[((params)>>2)] = data; break;
  6100. case 5: HEAP32[((params)>>2)] = Math.fround(data); break;
  6101. }
  6102. } else {
  6103. for (var i = 0; i < data.length; i++) {
  6104. switch (type) {
  6105. case 0: HEAP32[(((params)+(i*4))>>2)] = data[i]; break;
  6106. case 2: HEAPF32[(((params)+(i*4))>>2)] = data[i]; break;
  6107. case 5: HEAP32[(((params)+(i*4))>>2)] = Math.fround(data[i]); break;
  6108. }
  6109. }
  6110. }
  6111. }
  6112. function _emscripten_glGetVertexAttribfv(index, pname, params) {
  6113. // N.B. This function may only be called if the vertex attribute was specified using the function glVertexAttrib*f(),
  6114. // otherwise the results are undefined. (GLES3 spec 6.1.12)
  6115. emscriptenWebGLGetVertexAttrib(index, pname, params, 2);
  6116. }
  6117. function _emscripten_glGetVertexAttribiv(index, pname, params) {
  6118. // N.B. This function may only be called if the vertex attribute was specified using the function glVertexAttrib*f(),
  6119. // otherwise the results are undefined. (GLES3 spec 6.1.12)
  6120. emscriptenWebGLGetVertexAttrib(index, pname, params, 5);
  6121. }
  6122. function _emscripten_glHint(x0, x1) { GLctx['hint'](x0, x1) }
  6123. function _emscripten_glIsBuffer(buffer) {
  6124. var b = GL.buffers[buffer];
  6125. if (!b) return 0;
  6126. return GLctx.isBuffer(b);
  6127. }
  6128. function _emscripten_glIsEnabled(x0) { return GLctx['isEnabled'](x0) }
  6129. function _emscripten_glIsFramebuffer(framebuffer) {
  6130. var fb = GL.framebuffers[framebuffer];
  6131. if (!fb) return 0;
  6132. return GLctx.isFramebuffer(fb);
  6133. }
  6134. function _emscripten_glIsProgram(program) {
  6135. program = GL.programs[program];
  6136. if (!program) return 0;
  6137. return GLctx.isProgram(program);
  6138. }
  6139. function _emscripten_glIsQueryEXT(id) {
  6140. var query = GL.queries[id];
  6141. if (!query) return 0;
  6142. return GLctx.disjointTimerQueryExt['isQueryEXT'](query);
  6143. }
  6144. function _emscripten_glIsRenderbuffer(renderbuffer) {
  6145. var rb = GL.renderbuffers[renderbuffer];
  6146. if (!rb) return 0;
  6147. return GLctx.isRenderbuffer(rb);
  6148. }
  6149. function _emscripten_glIsShader(shader) {
  6150. var s = GL.shaders[shader];
  6151. if (!s) return 0;
  6152. return GLctx.isShader(s);
  6153. }
  6154. function _emscripten_glIsTexture(id) {
  6155. var texture = GL.textures[id];
  6156. if (!texture) return 0;
  6157. return GLctx.isTexture(texture);
  6158. }
  6159. function _emscripten_glIsVertexArrayOES(array) {
  6160. var vao = GL.vaos[array];
  6161. if (!vao) return 0;
  6162. return GLctx['isVertexArray'](vao);
  6163. }
  6164. function _emscripten_glLineWidth(x0) { GLctx['lineWidth'](x0) }
  6165. function _emscripten_glLinkProgram(program) {
  6166. program = GL.programs[program];
  6167. GLctx.linkProgram(program);
  6168. // Invalidate earlier computed uniform->ID mappings, those have now become stale
  6169. program.uniformLocsById = 0; // Mark as null-like so that glGetUniformLocation() knows to populate this again.
  6170. program.uniformSizeAndIdsByName = {};
  6171. }
  6172. function _emscripten_glPixelStorei(pname, param) {
  6173. if (pname == 0xCF5 /* GL_UNPACK_ALIGNMENT */) {
  6174. GL.unpackAlignment = param;
  6175. }
  6176. GLctx.pixelStorei(pname, param);
  6177. }
  6178. function _emscripten_glPolygonOffset(x0, x1) { GLctx['polygonOffset'](x0, x1) }
  6179. function _emscripten_glQueryCounterEXT(id, target) {
  6180. GLctx.disjointTimerQueryExt['queryCounterEXT'](GL.queries[id], target);
  6181. }
  6182. function computeUnpackAlignedImageSize(width, height, sizePerPixel, alignment) {
  6183. function roundedToNextMultipleOf(x, y) {
  6184. return (x + y - 1) & -y;
  6185. }
  6186. var plainRowSize = width * sizePerPixel;
  6187. var alignedRowSize = roundedToNextMultipleOf(plainRowSize, alignment);
  6188. return height * alignedRowSize;
  6189. }
  6190. function __colorChannelsInGlTextureFormat(format) {
  6191. // Micro-optimizations for size: map format to size by subtracting smallest enum value (0x1902) from all values first.
  6192. // Also omit the most common size value (1) from the list, which is assumed by formats not on the list.
  6193. var colorChannels = {
  6194. // 0x1902 /* GL_DEPTH_COMPONENT */ - 0x1902: 1,
  6195. // 0x1906 /* GL_ALPHA */ - 0x1902: 1,
  6196. 5: 3,
  6197. 6: 4,
  6198. // 0x1909 /* GL_LUMINANCE */ - 0x1902: 1,
  6199. 8: 2,
  6200. 29502: 3,
  6201. 29504: 4,
  6202. };
  6203. return colorChannels[format - 0x1902]||1;
  6204. }
  6205. function heapObjectForWebGLType(type) {
  6206. // Micro-optimization for size: Subtract lowest GL enum number (0x1400/* GL_BYTE */) from type to compare
  6207. // smaller values for the heap, for shorter generated code size.
  6208. // Also the type HEAPU16 is not tested for explicitly, but any unrecognized type will return out HEAPU16.
  6209. // (since most types are HEAPU16)
  6210. type -= 0x1400;
  6211. if (type == 1) return HEAPU8;
  6212. if (type == 4) return HEAP32;
  6213. if (type == 6) return HEAPF32;
  6214. if (type == 5
  6215. || type == 28922
  6216. )
  6217. return HEAPU32;
  6218. return HEAPU16;
  6219. }
  6220. function heapAccessShiftForWebGLHeap(heap) {
  6221. return 31 - Math.clz32(heap.BYTES_PER_ELEMENT);
  6222. }
  6223. function emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, internalFormat) {
  6224. var heap = heapObjectForWebGLType(type);
  6225. var shift = heapAccessShiftForWebGLHeap(heap);
  6226. var byteSize = 1<<shift;
  6227. var sizePerPixel = __colorChannelsInGlTextureFormat(format) * byteSize;
  6228. var bytes = computeUnpackAlignedImageSize(width, height, sizePerPixel, GL.unpackAlignment);
  6229. return heap.subarray(pixels >> shift, pixels + bytes >> shift);
  6230. }
  6231. function _emscripten_glReadPixels(x, y, width, height, format, type, pixels) {
  6232. var pixelData = emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, format);
  6233. if (!pixelData) {
  6234. GL.recordError(0x500/*GL_INVALID_ENUM*/);
  6235. return;
  6236. }
  6237. GLctx.readPixels(x, y, width, height, format, type, pixelData);
  6238. }
  6239. function _emscripten_glReleaseShaderCompiler() {
  6240. // NOP (as allowed by GLES 2.0 spec)
  6241. }
  6242. function _emscripten_glRenderbufferStorage(x0, x1, x2, x3) { GLctx['renderbufferStorage'](x0, x1, x2, x3) }
  6243. function _emscripten_glSampleCoverage(value, invert) {
  6244. GLctx.sampleCoverage(value, !!invert);
  6245. }
  6246. function _emscripten_glScissor(x0, x1, x2, x3) { GLctx['scissor'](x0, x1, x2, x3) }
  6247. function _emscripten_glShaderBinary() {
  6248. GL.recordError(0x500/*GL_INVALID_ENUM*/);
  6249. }
  6250. function _emscripten_glShaderSource(shader, count, string, length) {
  6251. var source = GL.getSource(shader, count, string, length);
  6252. GLctx.shaderSource(GL.shaders[shader], source);
  6253. }
  6254. function _emscripten_glStencilFunc(x0, x1, x2) { GLctx['stencilFunc'](x0, x1, x2) }
  6255. function _emscripten_glStencilFuncSeparate(x0, x1, x2, x3) { GLctx['stencilFuncSeparate'](x0, x1, x2, x3) }
  6256. function _emscripten_glStencilMask(x0) { GLctx['stencilMask'](x0) }
  6257. function _emscripten_glStencilMaskSeparate(x0, x1) { GLctx['stencilMaskSeparate'](x0, x1) }
  6258. function _emscripten_glStencilOp(x0, x1, x2) { GLctx['stencilOp'](x0, x1, x2) }
  6259. function _emscripten_glStencilOpSeparate(x0, x1, x2, x3) { GLctx['stencilOpSeparate'](x0, x1, x2, x3) }
  6260. function _emscripten_glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels) {
  6261. GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, pixels ? emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, internalFormat) : null);
  6262. }
  6263. function _emscripten_glTexParameterf(x0, x1, x2) { GLctx['texParameterf'](x0, x1, x2) }
  6264. function _emscripten_glTexParameterfv(target, pname, params) {
  6265. var param = HEAPF32[((params)>>2)];
  6266. GLctx.texParameterf(target, pname, param);
  6267. }
  6268. function _emscripten_glTexParameteri(x0, x1, x2) { GLctx['texParameteri'](x0, x1, x2) }
  6269. function _emscripten_glTexParameteriv(target, pname, params) {
  6270. var param = HEAP32[((params)>>2)];
  6271. GLctx.texParameteri(target, pname, param);
  6272. }
  6273. function _emscripten_glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels) {
  6274. var pixelData = null;
  6275. if (pixels) pixelData = emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, 0);
  6276. GLctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixelData);
  6277. }
  6278. function _emscripten_glUniform1f(location, v0) {
  6279. GLctx.uniform1f(webglGetUniformLocation(location), v0);
  6280. }
  6281. var miniTempWebGLFloatBuffers = [];
  6282. function _emscripten_glUniform1fv(location, count, value) {
  6283. if (count <= 288) {
  6284. // avoid allocation when uploading few enough uniforms
  6285. var view = miniTempWebGLFloatBuffers[count-1];
  6286. for (var i = 0; i < count; ++i) {
  6287. view[i] = HEAPF32[(((value)+(4*i))>>2)];
  6288. }
  6289. } else
  6290. {
  6291. var view = HEAPF32.subarray((value)>>2, (value+count*4)>>2);
  6292. }
  6293. GLctx.uniform1fv(webglGetUniformLocation(location), view);
  6294. }
  6295. function _emscripten_glUniform1i(location, v0) {
  6296. GLctx.uniform1i(webglGetUniformLocation(location), v0);
  6297. }
  6298. var __miniTempWebGLIntBuffers = [];
  6299. function _emscripten_glUniform1iv(location, count, value) {
  6300. if (count <= 288) {
  6301. // avoid allocation when uploading few enough uniforms
  6302. var view = __miniTempWebGLIntBuffers[count-1];
  6303. for (var i = 0; i < count; ++i) {
  6304. view[i] = HEAP32[(((value)+(4*i))>>2)];
  6305. }
  6306. } else
  6307. {
  6308. var view = HEAP32.subarray((value)>>2, (value+count*4)>>2);
  6309. }
  6310. GLctx.uniform1iv(webglGetUniformLocation(location), view);
  6311. }
  6312. function _emscripten_glUniform2f(location, v0, v1) {
  6313. GLctx.uniform2f(webglGetUniformLocation(location), v0, v1);
  6314. }
  6315. function _emscripten_glUniform2fv(location, count, value) {
  6316. if (count <= 144) {
  6317. // avoid allocation when uploading few enough uniforms
  6318. var view = miniTempWebGLFloatBuffers[2*count-1];
  6319. for (var i = 0; i < 2*count; i += 2) {
  6320. view[i] = HEAPF32[(((value)+(4*i))>>2)];
  6321. view[i+1] = HEAPF32[(((value)+(4*i+4))>>2)];
  6322. }
  6323. } else
  6324. {
  6325. var view = HEAPF32.subarray((value)>>2, (value+count*8)>>2);
  6326. }
  6327. GLctx.uniform2fv(webglGetUniformLocation(location), view);
  6328. }
  6329. function _emscripten_glUniform2i(location, v0, v1) {
  6330. GLctx.uniform2i(webglGetUniformLocation(location), v0, v1);
  6331. }
  6332. function _emscripten_glUniform2iv(location, count, value) {
  6333. if (count <= 144) {
  6334. // avoid allocation when uploading few enough uniforms
  6335. var view = __miniTempWebGLIntBuffers[2*count-1];
  6336. for (var i = 0; i < 2*count; i += 2) {
  6337. view[i] = HEAP32[(((value)+(4*i))>>2)];
  6338. view[i+1] = HEAP32[(((value)+(4*i+4))>>2)];
  6339. }
  6340. } else
  6341. {
  6342. var view = HEAP32.subarray((value)>>2, (value+count*8)>>2);
  6343. }
  6344. GLctx.uniform2iv(webglGetUniformLocation(location), view);
  6345. }
  6346. function _emscripten_glUniform3f(location, v0, v1, v2) {
  6347. GLctx.uniform3f(webglGetUniformLocation(location), v0, v1, v2);
  6348. }
  6349. function _emscripten_glUniform3fv(location, count, value) {
  6350. if (count <= 96) {
  6351. // avoid allocation when uploading few enough uniforms
  6352. var view = miniTempWebGLFloatBuffers[3*count-1];
  6353. for (var i = 0; i < 3*count; i += 3) {
  6354. view[i] = HEAPF32[(((value)+(4*i))>>2)];
  6355. view[i+1] = HEAPF32[(((value)+(4*i+4))>>2)];
  6356. view[i+2] = HEAPF32[(((value)+(4*i+8))>>2)];
  6357. }
  6358. } else
  6359. {
  6360. var view = HEAPF32.subarray((value)>>2, (value+count*12)>>2);
  6361. }
  6362. GLctx.uniform3fv(webglGetUniformLocation(location), view);
  6363. }
  6364. function _emscripten_glUniform3i(location, v0, v1, v2) {
  6365. GLctx.uniform3i(webglGetUniformLocation(location), v0, v1, v2);
  6366. }
  6367. function _emscripten_glUniform3iv(location, count, value) {
  6368. if (count <= 96) {
  6369. // avoid allocation when uploading few enough uniforms
  6370. var view = __miniTempWebGLIntBuffers[3*count-1];
  6371. for (var i = 0; i < 3*count; i += 3) {
  6372. view[i] = HEAP32[(((value)+(4*i))>>2)];
  6373. view[i+1] = HEAP32[(((value)+(4*i+4))>>2)];
  6374. view[i+2] = HEAP32[(((value)+(4*i+8))>>2)];
  6375. }
  6376. } else
  6377. {
  6378. var view = HEAP32.subarray((value)>>2, (value+count*12)>>2);
  6379. }
  6380. GLctx.uniform3iv(webglGetUniformLocation(location), view);
  6381. }
  6382. function _emscripten_glUniform4f(location, v0, v1, v2, v3) {
  6383. GLctx.uniform4f(webglGetUniformLocation(location), v0, v1, v2, v3);
  6384. }
  6385. function _emscripten_glUniform4fv(location, count, value) {
  6386. if (count <= 72) {
  6387. // avoid allocation when uploading few enough uniforms
  6388. var view = miniTempWebGLFloatBuffers[4*count-1];
  6389. // hoist the heap out of the loop for size and for pthreads+growth.
  6390. var heap = HEAPF32;
  6391. value >>= 2;
  6392. for (var i = 0; i < 4 * count; i += 4) {
  6393. var dst = value + i;
  6394. view[i] = heap[dst];
  6395. view[i + 1] = heap[dst + 1];
  6396. view[i + 2] = heap[dst + 2];
  6397. view[i + 3] = heap[dst + 3];
  6398. }
  6399. } else
  6400. {
  6401. var view = HEAPF32.subarray((value)>>2, (value+count*16)>>2);
  6402. }
  6403. GLctx.uniform4fv(webglGetUniformLocation(location), view);
  6404. }
  6405. function _emscripten_glUniform4i(location, v0, v1, v2, v3) {
  6406. GLctx.uniform4i(webglGetUniformLocation(location), v0, v1, v2, v3);
  6407. }
  6408. function _emscripten_glUniform4iv(location, count, value) {
  6409. if (count <= 72) {
  6410. // avoid allocation when uploading few enough uniforms
  6411. var view = __miniTempWebGLIntBuffers[4*count-1];
  6412. for (var i = 0; i < 4*count; i += 4) {
  6413. view[i] = HEAP32[(((value)+(4*i))>>2)];
  6414. view[i+1] = HEAP32[(((value)+(4*i+4))>>2)];
  6415. view[i+2] = HEAP32[(((value)+(4*i+8))>>2)];
  6416. view[i+3] = HEAP32[(((value)+(4*i+12))>>2)];
  6417. }
  6418. } else
  6419. {
  6420. var view = HEAP32.subarray((value)>>2, (value+count*16)>>2);
  6421. }
  6422. GLctx.uniform4iv(webglGetUniformLocation(location), view);
  6423. }
  6424. function _emscripten_glUniformMatrix2fv(location, count, transpose, value) {
  6425. if (count <= 72) {
  6426. // avoid allocation when uploading few enough uniforms
  6427. var view = miniTempWebGLFloatBuffers[4*count-1];
  6428. for (var i = 0; i < 4*count; i += 4) {
  6429. view[i] = HEAPF32[(((value)+(4*i))>>2)];
  6430. view[i+1] = HEAPF32[(((value)+(4*i+4))>>2)];
  6431. view[i+2] = HEAPF32[(((value)+(4*i+8))>>2)];
  6432. view[i+3] = HEAPF32[(((value)+(4*i+12))>>2)];
  6433. }
  6434. } else
  6435. {
  6436. var view = HEAPF32.subarray((value)>>2, (value+count*16)>>2);
  6437. }
  6438. GLctx.uniformMatrix2fv(webglGetUniformLocation(location), !!transpose, view);
  6439. }
  6440. function _emscripten_glUniformMatrix3fv(location, count, transpose, value) {
  6441. if (count <= 32) {
  6442. // avoid allocation when uploading few enough uniforms
  6443. var view = miniTempWebGLFloatBuffers[9*count-1];
  6444. for (var i = 0; i < 9*count; i += 9) {
  6445. view[i] = HEAPF32[(((value)+(4*i))>>2)];
  6446. view[i+1] = HEAPF32[(((value)+(4*i+4))>>2)];
  6447. view[i+2] = HEAPF32[(((value)+(4*i+8))>>2)];
  6448. view[i+3] = HEAPF32[(((value)+(4*i+12))>>2)];
  6449. view[i+4] = HEAPF32[(((value)+(4*i+16))>>2)];
  6450. view[i+5] = HEAPF32[(((value)+(4*i+20))>>2)];
  6451. view[i+6] = HEAPF32[(((value)+(4*i+24))>>2)];
  6452. view[i+7] = HEAPF32[(((value)+(4*i+28))>>2)];
  6453. view[i+8] = HEAPF32[(((value)+(4*i+32))>>2)];
  6454. }
  6455. } else
  6456. {
  6457. var view = HEAPF32.subarray((value)>>2, (value+count*36)>>2);
  6458. }
  6459. GLctx.uniformMatrix3fv(webglGetUniformLocation(location), !!transpose, view);
  6460. }
  6461. function _emscripten_glUniformMatrix4fv(location, count, transpose, value) {
  6462. if (count <= 18) {
  6463. // avoid allocation when uploading few enough uniforms
  6464. var view = miniTempWebGLFloatBuffers[16*count-1];
  6465. // hoist the heap out of the loop for size and for pthreads+growth.
  6466. var heap = HEAPF32;
  6467. value >>= 2;
  6468. for (var i = 0; i < 16 * count; i += 16) {
  6469. var dst = value + i;
  6470. view[i] = heap[dst];
  6471. view[i + 1] = heap[dst + 1];
  6472. view[i + 2] = heap[dst + 2];
  6473. view[i + 3] = heap[dst + 3];
  6474. view[i + 4] = heap[dst + 4];
  6475. view[i + 5] = heap[dst + 5];
  6476. view[i + 6] = heap[dst + 6];
  6477. view[i + 7] = heap[dst + 7];
  6478. view[i + 8] = heap[dst + 8];
  6479. view[i + 9] = heap[dst + 9];
  6480. view[i + 10] = heap[dst + 10];
  6481. view[i + 11] = heap[dst + 11];
  6482. view[i + 12] = heap[dst + 12];
  6483. view[i + 13] = heap[dst + 13];
  6484. view[i + 14] = heap[dst + 14];
  6485. view[i + 15] = heap[dst + 15];
  6486. }
  6487. } else
  6488. {
  6489. var view = HEAPF32.subarray((value)>>2, (value+count*64)>>2);
  6490. }
  6491. GLctx.uniformMatrix4fv(webglGetUniformLocation(location), !!transpose, view);
  6492. }
  6493. function _emscripten_glUseProgram(program) {
  6494. program = GL.programs[program];
  6495. GLctx.useProgram(program);
  6496. // Record the currently active program so that we can access the uniform
  6497. // mapping table of that program.
  6498. GLctx.currentProgram = program;
  6499. }
  6500. function _emscripten_glValidateProgram(program) {
  6501. GLctx.validateProgram(GL.programs[program]);
  6502. }
  6503. function _emscripten_glVertexAttrib1f(x0, x1) { GLctx['vertexAttrib1f'](x0, x1) }
  6504. function _emscripten_glVertexAttrib1fv(index, v) {
  6505. GLctx.vertexAttrib1f(index, HEAPF32[v>>2]);
  6506. }
  6507. function _emscripten_glVertexAttrib2f(x0, x1, x2) { GLctx['vertexAttrib2f'](x0, x1, x2) }
  6508. function _emscripten_glVertexAttrib2fv(index, v) {
  6509. GLctx.vertexAttrib2f(index, HEAPF32[v>>2], HEAPF32[v+4>>2]);
  6510. }
  6511. function _emscripten_glVertexAttrib3f(x0, x1, x2, x3) { GLctx['vertexAttrib3f'](x0, x1, x2, x3) }
  6512. function _emscripten_glVertexAttrib3fv(index, v) {
  6513. GLctx.vertexAttrib3f(index, HEAPF32[v>>2], HEAPF32[v+4>>2], HEAPF32[v+8>>2]);
  6514. }
  6515. function _emscripten_glVertexAttrib4f(x0, x1, x2, x3, x4) { GLctx['vertexAttrib4f'](x0, x1, x2, x3, x4) }
  6516. function _emscripten_glVertexAttrib4fv(index, v) {
  6517. GLctx.vertexAttrib4f(index, HEAPF32[v>>2], HEAPF32[v+4>>2], HEAPF32[v+8>>2], HEAPF32[v+12>>2]);
  6518. }
  6519. function _emscripten_glVertexAttribDivisorANGLE(index, divisor) {
  6520. GLctx['vertexAttribDivisor'](index, divisor);
  6521. }
  6522. function _emscripten_glVertexAttribPointer(index, size, type, normalized, stride, ptr) {
  6523. GLctx.vertexAttribPointer(index, size, type, !!normalized, stride, ptr);
  6524. }
  6525. function _emscripten_glViewport(x0, x1, x2, x3) { GLctx['viewport'](x0, x1, x2, x3) }
  6526. function _emscripten_has_asyncify() {
  6527. return 1;
  6528. }
  6529. function _emscripten_memcpy_big(dest, src, num) {
  6530. HEAPU8.copyWithin(dest, src, src + num);
  6531. }
  6532. function doRequestFullscreen(target, strategy) {
  6533. if (!JSEvents.fullscreenEnabled()) return -1;
  6534. target = findEventTarget(target);
  6535. if (!target) return -4;
  6536. if (!target.requestFullscreen
  6537. && !target.webkitRequestFullscreen
  6538. ) {
  6539. return -3;
  6540. }
  6541. var canPerformRequests = JSEvents.canPerformEventHandlerRequests();
  6542. // Queue this function call if we're not currently in an event handler and the user saw it appropriate to do so.
  6543. if (!canPerformRequests) {
  6544. if (strategy.deferUntilInEventHandler) {
  6545. JSEvents.deferCall(JSEvents_requestFullscreen, 1 /* priority over pointer lock */, [target, strategy]);
  6546. return 1;
  6547. }
  6548. return -2;
  6549. }
  6550. return JSEvents_requestFullscreen(target, strategy);
  6551. }
  6552. function _emscripten_request_fullscreen_strategy(target, deferUntilInEventHandler, fullscreenStrategy) {
  6553. var strategy = {
  6554. scaleMode: HEAP32[((fullscreenStrategy)>>2)],
  6555. canvasResolutionScaleMode: HEAP32[(((fullscreenStrategy)+(4))>>2)],
  6556. filteringMode: HEAP32[(((fullscreenStrategy)+(8))>>2)],
  6557. deferUntilInEventHandler: deferUntilInEventHandler,
  6558. canvasResizedCallback: HEAP32[(((fullscreenStrategy)+(12))>>2)],
  6559. canvasResizedCallbackUserData: HEAP32[(((fullscreenStrategy)+(16))>>2)]
  6560. };
  6561. return doRequestFullscreen(target, strategy);
  6562. }
  6563. function _emscripten_request_pointerlock(target, deferUntilInEventHandler) {
  6564. target = findEventTarget(target);
  6565. if (!target) return -4;
  6566. if (!target.requestPointerLock
  6567. ) {
  6568. return -1;
  6569. }
  6570. var canPerformRequests = JSEvents.canPerformEventHandlerRequests();
  6571. // Queue this function call if we're not currently in an event handler and the user saw it appropriate to do so.
  6572. if (!canPerformRequests) {
  6573. if (deferUntilInEventHandler) {
  6574. JSEvents.deferCall(requestPointerLock, 2 /* priority below fullscreen */, [target]);
  6575. return 1;
  6576. }
  6577. return -2;
  6578. }
  6579. return requestPointerLock(target);
  6580. }
  6581. function getHeapMax() {
  6582. // Stay one Wasm page short of 4GB: while e.g. Chrome is able to allocate
  6583. // full 4GB Wasm memories, the size will wrap back to 0 bytes in Wasm side
  6584. // for any code that deals with heap sizes, which would require special
  6585. // casing all heap size related code to treat 0 specially.
  6586. return 2147483648;
  6587. }
  6588. function emscripten_realloc_buffer(size) {
  6589. try {
  6590. // round size grow request up to wasm page size (fixed 64KB per spec)
  6591. wasmMemory.grow((size - buffer.byteLength + 65535) >>> 16); // .grow() takes a delta compared to the previous size
  6592. updateGlobalBufferAndViews(wasmMemory.buffer);
  6593. return 1 /*success*/;
  6594. } catch(e) {
  6595. err('emscripten_realloc_buffer: Attempted to grow heap from ' + buffer.byteLength + ' bytes to ' + size + ' bytes, but got error: ' + e);
  6596. }
  6597. // implicit 0 return to save code size (caller will cast "undefined" into 0
  6598. // anyhow)
  6599. }
  6600. function _emscripten_resize_heap(requestedSize) {
  6601. var oldSize = HEAPU8.length;
  6602. requestedSize = requestedSize >>> 0;
  6603. // With multithreaded builds, races can happen (another thread might increase the size
  6604. // in between), so return a failure, and let the caller retry.
  6605. assert(requestedSize > oldSize);
  6606. // Memory resize rules:
  6607. // 1. Always increase heap size to at least the requested size, rounded up
  6608. // to next page multiple.
  6609. // 2a. If MEMORY_GROWTH_LINEAR_STEP == -1, excessively resize the heap
  6610. // geometrically: increase the heap size according to
  6611. // MEMORY_GROWTH_GEOMETRIC_STEP factor (default +20%), At most
  6612. // overreserve by MEMORY_GROWTH_GEOMETRIC_CAP bytes (default 96MB).
  6613. // 2b. If MEMORY_GROWTH_LINEAR_STEP != -1, excessively resize the heap
  6614. // linearly: increase the heap size by at least
  6615. // MEMORY_GROWTH_LINEAR_STEP bytes.
  6616. // 3. Max size for the heap is capped at 2048MB-WASM_PAGE_SIZE, or by
  6617. // MAXIMUM_MEMORY, or by ASAN limit, depending on which is smallest
  6618. // 4. If we were unable to allocate as much memory, it may be due to
  6619. // over-eager decision to excessively reserve due to (3) above.
  6620. // Hence if an allocation fails, cut down on the amount of excess
  6621. // growth, in an attempt to succeed to perform a smaller allocation.
  6622. // A limit is set for how much we can grow. We should not exceed that
  6623. // (the wasm binary specifies it, so if we tried, we'd fail anyhow).
  6624. var maxHeapSize = getHeapMax();
  6625. if (requestedSize > maxHeapSize) {
  6626. err('Cannot enlarge memory, asked to go up to ' + requestedSize + ' bytes, but the limit is ' + maxHeapSize + ' bytes!');
  6627. return false;
  6628. }
  6629. let alignUp = (x, multiple) => x + (multiple - x % multiple) % multiple;
  6630. // Loop through potential heap size increases. If we attempt a too eager
  6631. // reservation that fails, cut down on the attempted size and reserve a
  6632. // smaller bump instead. (max 3 times, chosen somewhat arbitrarily)
  6633. for (var cutDown = 1; cutDown <= 4; cutDown *= 2) {
  6634. var overGrownHeapSize = oldSize * (1 + 0.2 / cutDown); // ensure geometric growth
  6635. // but limit overreserving (default to capping at +96MB overgrowth at most)
  6636. overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296 );
  6637. var newSize = Math.min(maxHeapSize, alignUp(Math.max(requestedSize, overGrownHeapSize), 65536));
  6638. var replacement = emscripten_realloc_buffer(newSize);
  6639. if (replacement) {
  6640. return true;
  6641. }
  6642. }
  6643. err('Failed to grow the heap from ' + oldSize + ' bytes to ' + newSize + ' bytes, not enough memory!');
  6644. return false;
  6645. }
  6646. function _emscripten_sample_gamepad_data() {
  6647. return (JSEvents.lastGamepadState = (navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : null)))
  6648. ? 0 : -1;
  6649. }
  6650. function registerBeforeUnloadEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString) {
  6651. var beforeUnloadEventHandlerFunc = function(ev) {
  6652. var e = ev || event;
  6653. // Note: This is always called on the main browser thread, since it needs synchronously return a value!
  6654. var confirmationMessage = ((a1, a2, a3) => dynCall_iiii.apply(null, [callbackfunc, a1, a2, a3]))(eventTypeId, 0, userData);
  6655. if (confirmationMessage) {
  6656. confirmationMessage = UTF8ToString(confirmationMessage);
  6657. }
  6658. if (confirmationMessage) {
  6659. e.preventDefault();
  6660. e.returnValue = confirmationMessage;
  6661. return confirmationMessage;
  6662. }
  6663. };
  6664. var eventHandler = {
  6665. target: findEventTarget(target),
  6666. eventTypeString: eventTypeString,
  6667. callbackfunc: callbackfunc,
  6668. handlerFunc: beforeUnloadEventHandlerFunc,
  6669. useCapture: useCapture
  6670. };
  6671. JSEvents.registerOrRemoveHandler(eventHandler);
  6672. }
  6673. function _emscripten_set_beforeunload_callback_on_thread(userData, callbackfunc, targetThread) {
  6674. if (typeof onbeforeunload == 'undefined') return -1;
  6675. // beforeunload callback can only be registered on the main browser thread, because the page will go away immediately after returning from the handler,
  6676. // and there is no time to start proxying it anywhere.
  6677. if (targetThread !== 1) return -5;
  6678. registerBeforeUnloadEventCallback(2, userData, true, callbackfunc, 28, "beforeunload");
  6679. return 0;
  6680. }
  6681. function registerFocusEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {
  6682. if (!JSEvents.focusEvent) JSEvents.focusEvent = _malloc( 256 );
  6683. var focusEventHandlerFunc = function(ev) {
  6684. var e = ev || event;
  6685. var nodeName = JSEvents.getNodeNameForTarget(e.target);
  6686. var id = e.target.id ? e.target.id : '';
  6687. var focusEvent = JSEvents.focusEvent;
  6688. stringToUTF8(nodeName, focusEvent + 0, 128);
  6689. stringToUTF8(id, focusEvent + 128, 128);
  6690. if (((a1, a2, a3) => dynCall_iiii.apply(null, [callbackfunc, a1, a2, a3]))(eventTypeId, focusEvent, userData)) e.preventDefault();
  6691. };
  6692. var eventHandler = {
  6693. target: findEventTarget(target),
  6694. eventTypeString: eventTypeString,
  6695. callbackfunc: callbackfunc,
  6696. handlerFunc: focusEventHandlerFunc,
  6697. useCapture: useCapture
  6698. };
  6699. JSEvents.registerOrRemoveHandler(eventHandler);
  6700. }
  6701. function _emscripten_set_blur_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  6702. registerFocusEventCallback(target, userData, useCapture, callbackfunc, 12, "blur", targetThread);
  6703. return 0;
  6704. }
  6705. function _emscripten_set_element_css_size(target, width, height) {
  6706. target = findEventTarget(target);
  6707. if (!target) return -4;
  6708. target.style.width = width + "px";
  6709. target.style.height = height + "px";
  6710. return 0;
  6711. }
  6712. function _emscripten_set_focus_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  6713. registerFocusEventCallback(target, userData, useCapture, callbackfunc, 13, "focus", targetThread);
  6714. return 0;
  6715. }
  6716. function fillFullscreenChangeEventData(eventStruct) {
  6717. var fullscreenElement = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement;
  6718. var isFullscreen = !!fullscreenElement;
  6719. // Assigning a boolean to HEAP32 with expected type coercion.
  6720. /** @suppress{checkTypes} */
  6721. HEAP32[((eventStruct)>>2)] = isFullscreen;
  6722. HEAP32[(((eventStruct)+(4))>>2)] = JSEvents.fullscreenEnabled();
  6723. // If transitioning to fullscreen, report info about the element that is now fullscreen.
  6724. // If transitioning to windowed mode, report info about the element that just was fullscreen.
  6725. var reportedElement = isFullscreen ? fullscreenElement : JSEvents.previousFullscreenElement;
  6726. var nodeName = JSEvents.getNodeNameForTarget(reportedElement);
  6727. var id = (reportedElement && reportedElement.id) ? reportedElement.id : '';
  6728. stringToUTF8(nodeName, eventStruct + 8, 128);
  6729. stringToUTF8(id, eventStruct + 136, 128);
  6730. HEAP32[(((eventStruct)+(264))>>2)] = reportedElement ? reportedElement.clientWidth : 0;
  6731. HEAP32[(((eventStruct)+(268))>>2)] = reportedElement ? reportedElement.clientHeight : 0;
  6732. HEAP32[(((eventStruct)+(272))>>2)] = screen.width;
  6733. HEAP32[(((eventStruct)+(276))>>2)] = screen.height;
  6734. if (isFullscreen) {
  6735. JSEvents.previousFullscreenElement = fullscreenElement;
  6736. }
  6737. }
  6738. function registerFullscreenChangeEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {
  6739. if (!JSEvents.fullscreenChangeEvent) JSEvents.fullscreenChangeEvent = _malloc( 280 );
  6740. var fullscreenChangeEventhandlerFunc = function(ev) {
  6741. var e = ev || event;
  6742. var fullscreenChangeEvent = JSEvents.fullscreenChangeEvent;
  6743. fillFullscreenChangeEventData(fullscreenChangeEvent);
  6744. if (((a1, a2, a3) => dynCall_iiii.apply(null, [callbackfunc, a1, a2, a3]))(eventTypeId, fullscreenChangeEvent, userData)) e.preventDefault();
  6745. };
  6746. var eventHandler = {
  6747. target: target,
  6748. eventTypeString: eventTypeString,
  6749. callbackfunc: callbackfunc,
  6750. handlerFunc: fullscreenChangeEventhandlerFunc,
  6751. useCapture: useCapture
  6752. };
  6753. JSEvents.registerOrRemoveHandler(eventHandler);
  6754. }
  6755. function _emscripten_set_fullscreenchange_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  6756. if (!JSEvents.fullscreenEnabled()) return -1;
  6757. target = findEventTarget(target);
  6758. if (!target) return -4;
  6759. registerFullscreenChangeEventCallback(target, userData, useCapture, callbackfunc, 19, "fullscreenchange", targetThread);
  6760. // Unprefixed Fullscreen API shipped in Chromium 71 (https://bugs.chromium.org/p/chromium/issues/detail?id=383813)
  6761. // 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.
  6762. registerFullscreenChangeEventCallback(target, userData, useCapture, callbackfunc, 19, "webkitfullscreenchange", targetThread);
  6763. return 0;
  6764. }
  6765. function registerGamepadEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {
  6766. if (!JSEvents.gamepadEvent) JSEvents.gamepadEvent = _malloc( 1432 );
  6767. var gamepadEventHandlerFunc = function(ev) {
  6768. var e = ev || event;
  6769. var gamepadEvent = JSEvents.gamepadEvent;
  6770. fillGamepadEventData(gamepadEvent, e["gamepad"]);
  6771. if (((a1, a2, a3) => dynCall_iiii.apply(null, [callbackfunc, a1, a2, a3]))(eventTypeId, gamepadEvent, userData)) e.preventDefault();
  6772. };
  6773. var eventHandler = {
  6774. target: findEventTarget(target),
  6775. allowsDeferredCalls: true,
  6776. eventTypeString: eventTypeString,
  6777. callbackfunc: callbackfunc,
  6778. handlerFunc: gamepadEventHandlerFunc,
  6779. useCapture: useCapture
  6780. };
  6781. JSEvents.registerOrRemoveHandler(eventHandler);
  6782. }
  6783. function _emscripten_set_gamepadconnected_callback_on_thread(userData, useCapture, callbackfunc, targetThread) {
  6784. if (!navigator.getGamepads && !navigator.webkitGetGamepads) return -1;
  6785. registerGamepadEventCallback(2, userData, useCapture, callbackfunc, 26, "gamepadconnected", targetThread);
  6786. return 0;
  6787. }
  6788. function _emscripten_set_gamepaddisconnected_callback_on_thread(userData, useCapture, callbackfunc, targetThread) {
  6789. if (!navigator.getGamepads && !navigator.webkitGetGamepads) return -1;
  6790. registerGamepadEventCallback(2, userData, useCapture, callbackfunc, 27, "gamepaddisconnected", targetThread);
  6791. return 0;
  6792. }
  6793. function registerKeyEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {
  6794. if (!JSEvents.keyEvent) JSEvents.keyEvent = _malloc( 176 );
  6795. var keyEventHandlerFunc = function(e) {
  6796. assert(e);
  6797. var keyEventData = JSEvents.keyEvent;
  6798. HEAPF64[((keyEventData)>>3)] = e.timeStamp;
  6799. var idx = keyEventData >> 2;
  6800. HEAP32[idx + 2] = e.location;
  6801. HEAP32[idx + 3] = e.ctrlKey;
  6802. HEAP32[idx + 4] = e.shiftKey;
  6803. HEAP32[idx + 5] = e.altKey;
  6804. HEAP32[idx + 6] = e.metaKey;
  6805. HEAP32[idx + 7] = e.repeat;
  6806. HEAP32[idx + 8] = e.charCode;
  6807. HEAP32[idx + 9] = e.keyCode;
  6808. HEAP32[idx + 10] = e.which;
  6809. stringToUTF8(e.key || '', keyEventData + 44, 32);
  6810. stringToUTF8(e.code || '', keyEventData + 76, 32);
  6811. stringToUTF8(e.char || '', keyEventData + 108, 32);
  6812. stringToUTF8(e.locale || '', keyEventData + 140, 32);
  6813. if (((a1, a2, a3) => dynCall_iiii.apply(null, [callbackfunc, a1, a2, a3]))(eventTypeId, keyEventData, userData)) e.preventDefault();
  6814. };
  6815. var eventHandler = {
  6816. target: findEventTarget(target),
  6817. allowsDeferredCalls: true,
  6818. eventTypeString: eventTypeString,
  6819. callbackfunc: callbackfunc,
  6820. handlerFunc: keyEventHandlerFunc,
  6821. useCapture: useCapture
  6822. };
  6823. JSEvents.registerOrRemoveHandler(eventHandler);
  6824. }
  6825. function _emscripten_set_keydown_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  6826. registerKeyEventCallback(target, userData, useCapture, callbackfunc, 2, "keydown", targetThread);
  6827. return 0;
  6828. }
  6829. function _emscripten_set_keypress_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  6830. registerKeyEventCallback(target, userData, useCapture, callbackfunc, 1, "keypress", targetThread);
  6831. return 0;
  6832. }
  6833. function _emscripten_set_keyup_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  6834. registerKeyEventCallback(target, userData, useCapture, callbackfunc, 3, "keyup", targetThread);
  6835. return 0;
  6836. }
  6837. function _emscripten_set_main_loop(func, fps, simulateInfiniteLoop) {
  6838. var browserIterationFunc = (() => dynCall_v.call(null, func));
  6839. setMainLoop(browserIterationFunc, fps, simulateInfiniteLoop);
  6840. }
  6841. function fillMouseEventData(eventStruct, e, target) {
  6842. assert(eventStruct % 4 == 0);
  6843. HEAPF64[((eventStruct)>>3)] = e.timeStamp;
  6844. var idx = eventStruct >> 2;
  6845. HEAP32[idx + 2] = e.screenX;
  6846. HEAP32[idx + 3] = e.screenY;
  6847. HEAP32[idx + 4] = e.clientX;
  6848. HEAP32[idx + 5] = e.clientY;
  6849. HEAP32[idx + 6] = e.ctrlKey;
  6850. HEAP32[idx + 7] = e.shiftKey;
  6851. HEAP32[idx + 8] = e.altKey;
  6852. HEAP32[idx + 9] = e.metaKey;
  6853. HEAP16[idx*2 + 20] = e.button;
  6854. HEAP16[idx*2 + 21] = e.buttons;
  6855. HEAP32[idx + 11] = e["movementX"]
  6856. ;
  6857. HEAP32[idx + 12] = e["movementY"]
  6858. ;
  6859. var rect = getBoundingClientRect(target);
  6860. HEAP32[idx + 13] = e.clientX - rect.left;
  6861. HEAP32[idx + 14] = e.clientY - rect.top;
  6862. }
  6863. function registerMouseEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {
  6864. if (!JSEvents.mouseEvent) JSEvents.mouseEvent = _malloc( 72 );
  6865. target = findEventTarget(target);
  6866. var mouseEventHandlerFunc = function(ev) {
  6867. var e = ev || event;
  6868. // TODO: Make this access thread safe, or this could update live while app is reading it.
  6869. fillMouseEventData(JSEvents.mouseEvent, e, target);
  6870. if (((a1, a2, a3) => dynCall_iiii.apply(null, [callbackfunc, a1, a2, a3]))(eventTypeId, JSEvents.mouseEvent, userData)) e.preventDefault();
  6871. };
  6872. var eventHandler = {
  6873. target: target,
  6874. allowsDeferredCalls: eventTypeString != 'mousemove' && eventTypeString != 'mouseenter' && eventTypeString != 'mouseleave', // Mouse move events do not allow fullscreen/pointer lock requests to be handled in them!
  6875. eventTypeString: eventTypeString,
  6876. callbackfunc: callbackfunc,
  6877. handlerFunc: mouseEventHandlerFunc,
  6878. useCapture: useCapture
  6879. };
  6880. JSEvents.registerOrRemoveHandler(eventHandler);
  6881. }
  6882. function _emscripten_set_mousedown_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  6883. registerMouseEventCallback(target, userData, useCapture, callbackfunc, 5, "mousedown", targetThread);
  6884. return 0;
  6885. }
  6886. function _emscripten_set_mouseenter_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  6887. registerMouseEventCallback(target, userData, useCapture, callbackfunc, 33, "mouseenter", targetThread);
  6888. return 0;
  6889. }
  6890. function _emscripten_set_mouseleave_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  6891. registerMouseEventCallback(target, userData, useCapture, callbackfunc, 34, "mouseleave", targetThread);
  6892. return 0;
  6893. }
  6894. function _emscripten_set_mousemove_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  6895. registerMouseEventCallback(target, userData, useCapture, callbackfunc, 8, "mousemove", targetThread);
  6896. return 0;
  6897. }
  6898. function _emscripten_set_mouseup_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  6899. registerMouseEventCallback(target, userData, useCapture, callbackfunc, 6, "mouseup", targetThread);
  6900. return 0;
  6901. }
  6902. function fillPointerlockChangeEventData(eventStruct) {
  6903. var pointerLockElement = document.pointerLockElement || document.mozPointerLockElement || document.webkitPointerLockElement || document.msPointerLockElement;
  6904. var isPointerlocked = !!pointerLockElement;
  6905. // Assigning a boolean to HEAP32 with expected type coercion.
  6906. /** @suppress{checkTypes} */
  6907. HEAP32[((eventStruct)>>2)] = isPointerlocked;
  6908. var nodeName = JSEvents.getNodeNameForTarget(pointerLockElement);
  6909. var id = (pointerLockElement && pointerLockElement.id) ? pointerLockElement.id : '';
  6910. stringToUTF8(nodeName, eventStruct + 4, 128);
  6911. stringToUTF8(id, eventStruct + 132, 128);
  6912. }
  6913. function registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {
  6914. if (!JSEvents.pointerlockChangeEvent) JSEvents.pointerlockChangeEvent = _malloc( 260 );
  6915. var pointerlockChangeEventHandlerFunc = function(ev) {
  6916. var e = ev || event;
  6917. var pointerlockChangeEvent = JSEvents.pointerlockChangeEvent;
  6918. fillPointerlockChangeEventData(pointerlockChangeEvent);
  6919. if (((a1, a2, a3) => dynCall_iiii.apply(null, [callbackfunc, a1, a2, a3]))(eventTypeId, pointerlockChangeEvent, userData)) e.preventDefault();
  6920. };
  6921. var eventHandler = {
  6922. target: target,
  6923. eventTypeString: eventTypeString,
  6924. callbackfunc: callbackfunc,
  6925. handlerFunc: pointerlockChangeEventHandlerFunc,
  6926. useCapture: useCapture
  6927. };
  6928. JSEvents.registerOrRemoveHandler(eventHandler);
  6929. }
  6930. /** @suppress {missingProperties} */
  6931. function _emscripten_set_pointerlockchange_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  6932. // TODO: Currently not supported in pthreads or in --proxy-to-worker mode. (In pthreads mode, document object is not defined)
  6933. if (!document || !document.body || (!document.body.requestPointerLock && !document.body.mozRequestPointerLock && !document.body.webkitRequestPointerLock && !document.body.msRequestPointerLock)) {
  6934. return -1;
  6935. }
  6936. target = findEventTarget(target);
  6937. if (!target) return -4;
  6938. registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "pointerlockchange", targetThread);
  6939. registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "mozpointerlockchange", targetThread);
  6940. registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "webkitpointerlockchange", targetThread);
  6941. registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "mspointerlockchange", targetThread);
  6942. return 0;
  6943. }
  6944. function registerUiEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {
  6945. if (!JSEvents.uiEvent) JSEvents.uiEvent = _malloc( 36 );
  6946. target = findEventTarget(target);
  6947. var uiEventHandlerFunc = function(ev) {
  6948. var e = ev || event;
  6949. if (e.target != target) {
  6950. // Never take ui events such as scroll via a 'bubbled' route, but always from the direct element that
  6951. // was targeted. Otherwise e.g. if app logs a message in response to a page scroll, the Emscripten log
  6952. // message box could cause to scroll, generating a new (bubbled) scroll message, causing a new log print,
  6953. // causing a new scroll, etc..
  6954. return;
  6955. }
  6956. var b = document.body; // Take document.body to a variable, Closure compiler does not outline access to it on its own.
  6957. if (!b) {
  6958. // During a page unload 'body' can be null, with "Cannot read property 'clientWidth' of null" being thrown
  6959. return;
  6960. }
  6961. var uiEvent = JSEvents.uiEvent;
  6962. HEAP32[((uiEvent)>>2)] = e.detail;
  6963. HEAP32[(((uiEvent)+(4))>>2)] = b.clientWidth;
  6964. HEAP32[(((uiEvent)+(8))>>2)] = b.clientHeight;
  6965. HEAP32[(((uiEvent)+(12))>>2)] = innerWidth;
  6966. HEAP32[(((uiEvent)+(16))>>2)] = innerHeight;
  6967. HEAP32[(((uiEvent)+(20))>>2)] = outerWidth;
  6968. HEAP32[(((uiEvent)+(24))>>2)] = outerHeight;
  6969. HEAP32[(((uiEvent)+(28))>>2)] = pageXOffset;
  6970. HEAP32[(((uiEvent)+(32))>>2)] = pageYOffset;
  6971. if (((a1, a2, a3) => dynCall_iiii.apply(null, [callbackfunc, a1, a2, a3]))(eventTypeId, uiEvent, userData)) e.preventDefault();
  6972. };
  6973. var eventHandler = {
  6974. target: target,
  6975. eventTypeString: eventTypeString,
  6976. callbackfunc: callbackfunc,
  6977. handlerFunc: uiEventHandlerFunc,
  6978. useCapture: useCapture
  6979. };
  6980. JSEvents.registerOrRemoveHandler(eventHandler);
  6981. }
  6982. function _emscripten_set_resize_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  6983. registerUiEventCallback(target, userData, useCapture, callbackfunc, 10, "resize", targetThread);
  6984. return 0;
  6985. }
  6986. function registerTouchEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {
  6987. if (!JSEvents.touchEvent) JSEvents.touchEvent = _malloc( 1696 );
  6988. target = findEventTarget(target);
  6989. var touchEventHandlerFunc = function(e) {
  6990. assert(e);
  6991. var t, touches = {}, et = e.touches;
  6992. // To ease marshalling different kinds of touches that browser reports (all touches are listed in e.touches,
  6993. // only changed touches in e.changedTouches, and touches on target at a.targetTouches), mark a boolean in
  6994. // each Touch object so that we can later loop only once over all touches we see to marshall over to Wasm.
  6995. for (var i = 0; i < et.length; ++i) {
  6996. t = et[i];
  6997. // Browser might recycle the generated Touch objects between each frame (Firefox on Android), so reset any
  6998. // changed/target states we may have set from previous frame.
  6999. t.isChanged = t.onTarget = 0;
  7000. touches[t.identifier] = t;
  7001. }
  7002. // Mark which touches are part of the changedTouches list.
  7003. for (var i = 0; i < e.changedTouches.length; ++i) {
  7004. t = e.changedTouches[i];
  7005. t.isChanged = 1;
  7006. touches[t.identifier] = t;
  7007. }
  7008. // Mark which touches are part of the targetTouches list.
  7009. for (var i = 0; i < e.targetTouches.length; ++i) {
  7010. touches[e.targetTouches[i].identifier].onTarget = 1;
  7011. }
  7012. var touchEvent = JSEvents.touchEvent;
  7013. HEAPF64[((touchEvent)>>3)] = e.timeStamp;
  7014. var idx = touchEvent>>2; // Pre-shift the ptr to index to HEAP32 to save code size
  7015. HEAP32[idx + 3] = e.ctrlKey;
  7016. HEAP32[idx + 4] = e.shiftKey;
  7017. HEAP32[idx + 5] = e.altKey;
  7018. HEAP32[idx + 6] = e.metaKey;
  7019. idx += 7; // Advance to the start of the touch array.
  7020. var targetRect = getBoundingClientRect(target);
  7021. var numTouches = 0;
  7022. for (var i in touches) {
  7023. t = touches[i];
  7024. HEAP32[idx + 0] = t.identifier;
  7025. HEAP32[idx + 1] = t.screenX;
  7026. HEAP32[idx + 2] = t.screenY;
  7027. HEAP32[idx + 3] = t.clientX;
  7028. HEAP32[idx + 4] = t.clientY;
  7029. HEAP32[idx + 5] = t.pageX;
  7030. HEAP32[idx + 6] = t.pageY;
  7031. HEAP32[idx + 7] = t.isChanged;
  7032. HEAP32[idx + 8] = t.onTarget;
  7033. HEAP32[idx + 9] = t.clientX - targetRect.left;
  7034. HEAP32[idx + 10] = t.clientY - targetRect.top;
  7035. idx += 13;
  7036. if (++numTouches > 31) {
  7037. break;
  7038. }
  7039. }
  7040. HEAP32[(((touchEvent)+(8))>>2)] = numTouches;
  7041. if (((a1, a2, a3) => dynCall_iiii.apply(null, [callbackfunc, a1, a2, a3]))(eventTypeId, touchEvent, userData)) e.preventDefault();
  7042. };
  7043. var eventHandler = {
  7044. target: target,
  7045. allowsDeferredCalls: eventTypeString == 'touchstart' || eventTypeString == 'touchend',
  7046. eventTypeString: eventTypeString,
  7047. callbackfunc: callbackfunc,
  7048. handlerFunc: touchEventHandlerFunc,
  7049. useCapture: useCapture
  7050. };
  7051. JSEvents.registerOrRemoveHandler(eventHandler);
  7052. }
  7053. function _emscripten_set_touchcancel_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  7054. registerTouchEventCallback(target, userData, useCapture, callbackfunc, 25, "touchcancel", targetThread);
  7055. return 0;
  7056. }
  7057. function _emscripten_set_touchend_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  7058. registerTouchEventCallback(target, userData, useCapture, callbackfunc, 23, "touchend", targetThread);
  7059. return 0;
  7060. }
  7061. function _emscripten_set_touchmove_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  7062. registerTouchEventCallback(target, userData, useCapture, callbackfunc, 24, "touchmove", targetThread);
  7063. return 0;
  7064. }
  7065. function _emscripten_set_touchstart_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  7066. registerTouchEventCallback(target, userData, useCapture, callbackfunc, 22, "touchstart", targetThread);
  7067. return 0;
  7068. }
  7069. function fillVisibilityChangeEventData(eventStruct) {
  7070. var visibilityStates = [ "hidden", "visible", "prerender", "unloaded" ];
  7071. var visibilityState = visibilityStates.indexOf(document.visibilityState);
  7072. // Assigning a boolean to HEAP32 with expected type coercion.
  7073. /** @suppress{checkTypes} */
  7074. HEAP32[((eventStruct)>>2)] = document.hidden;
  7075. HEAP32[(((eventStruct)+(4))>>2)] = visibilityState;
  7076. }
  7077. function registerVisibilityChangeEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {
  7078. if (!JSEvents.visibilityChangeEvent) JSEvents.visibilityChangeEvent = _malloc( 8 );
  7079. var visibilityChangeEventHandlerFunc = function(ev) {
  7080. var e = ev || event;
  7081. var visibilityChangeEvent = JSEvents.visibilityChangeEvent;
  7082. fillVisibilityChangeEventData(visibilityChangeEvent);
  7083. if (((a1, a2, a3) => dynCall_iiii.apply(null, [callbackfunc, a1, a2, a3]))(eventTypeId, visibilityChangeEvent, userData)) e.preventDefault();
  7084. };
  7085. var eventHandler = {
  7086. target: target,
  7087. eventTypeString: eventTypeString,
  7088. callbackfunc: callbackfunc,
  7089. handlerFunc: visibilityChangeEventHandlerFunc,
  7090. useCapture: useCapture
  7091. };
  7092. JSEvents.registerOrRemoveHandler(eventHandler);
  7093. }
  7094. function _emscripten_set_visibilitychange_callback_on_thread(userData, useCapture, callbackfunc, targetThread) {
  7095. if (!specialHTMLTargets[1]) {
  7096. return -4;
  7097. }
  7098. registerVisibilityChangeEventCallback(specialHTMLTargets[1], userData, useCapture, callbackfunc, 21, "visibilitychange", targetThread);
  7099. return 0;
  7100. }
  7101. function registerWheelEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {
  7102. if (!JSEvents.wheelEvent) JSEvents.wheelEvent = _malloc( 104 );
  7103. // The DOM Level 3 events spec event 'wheel'
  7104. var wheelHandlerFunc = function(ev) {
  7105. var e = ev || event;
  7106. var wheelEvent = JSEvents.wheelEvent;
  7107. fillMouseEventData(wheelEvent, e, target);
  7108. HEAPF64[(((wheelEvent)+(72))>>3)] = e["deltaX"];
  7109. HEAPF64[(((wheelEvent)+(80))>>3)] = e["deltaY"];
  7110. HEAPF64[(((wheelEvent)+(88))>>3)] = e["deltaZ"];
  7111. HEAP32[(((wheelEvent)+(96))>>2)] = e["deltaMode"];
  7112. if (((a1, a2, a3) => dynCall_iiii.apply(null, [callbackfunc, a1, a2, a3]))(eventTypeId, wheelEvent, userData)) e.preventDefault();
  7113. };
  7114. var eventHandler = {
  7115. target: target,
  7116. allowsDeferredCalls: true,
  7117. eventTypeString: eventTypeString,
  7118. callbackfunc: callbackfunc,
  7119. handlerFunc: wheelHandlerFunc,
  7120. useCapture: useCapture
  7121. };
  7122. JSEvents.registerOrRemoveHandler(eventHandler);
  7123. }
  7124. function _emscripten_set_wheel_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  7125. target = findEventTarget(target);
  7126. if (typeof target.onwheel != 'undefined') {
  7127. registerWheelEventCallback(target, userData, useCapture, callbackfunc, 9, "wheel", targetThread);
  7128. return 0;
  7129. } else {
  7130. return -1;
  7131. }
  7132. }
  7133. function _emscripten_set_window_title(title) {
  7134. setWindowTitle(UTF8ToString(title));
  7135. }
  7136. function _emscripten_sleep(ms) {
  7137. // emscripten_sleep() does not return a value, but we still need a |return|
  7138. // here for stack switching support (ASYNCIFY=2). In that mode this function
  7139. // returns a Promise instead of nothing, and that Promise is what tells the
  7140. // wasm VM to pause the stack.
  7141. return Asyncify.handleSleep((wakeUp) => safeSetTimeout(wakeUp, ms));
  7142. }
  7143. var ENV = {};
  7144. function getExecutableName() {
  7145. return thisProgram || './this.program';
  7146. }
  7147. function getEnvStrings() {
  7148. if (!getEnvStrings.strings) {
  7149. // Default values.
  7150. // Browser language detection #8751
  7151. var lang = ((typeof navigator == 'object' && navigator.languages && navigator.languages[0]) || 'C').replace('-', '_') + '.UTF-8';
  7152. var env = {
  7153. 'USER': 'web_user',
  7154. 'LOGNAME': 'web_user',
  7155. 'PATH': '/',
  7156. 'PWD': '/',
  7157. 'HOME': '/home/web_user',
  7158. 'LANG': lang,
  7159. '_': getExecutableName()
  7160. };
  7161. // Apply the user-provided values, if any.
  7162. for (var x in ENV) {
  7163. // x is a key in ENV; if ENV[x] is undefined, that means it was
  7164. // explicitly set to be so. We allow user code to do that to
  7165. // force variables with default values to remain unset.
  7166. if (ENV[x] === undefined) delete env[x];
  7167. else env[x] = ENV[x];
  7168. }
  7169. var strings = [];
  7170. for (var x in env) {
  7171. strings.push(x + '=' + env[x]);
  7172. }
  7173. getEnvStrings.strings = strings;
  7174. }
  7175. return getEnvStrings.strings;
  7176. }
  7177. /** @param {boolean=} dontAddNull */
  7178. function writeAsciiToMemory(str, buffer, dontAddNull) {
  7179. for (var i = 0; i < str.length; ++i) {
  7180. assert(str.charCodeAt(i) === (str.charCodeAt(i) & 0xff));
  7181. HEAP8[((buffer++)>>0)] = str.charCodeAt(i);
  7182. }
  7183. // Null-terminate the pointer to the HEAP.
  7184. if (!dontAddNull) HEAP8[((buffer)>>0)] = 0;
  7185. }
  7186. function _environ_get(__environ, environ_buf) {
  7187. var bufSize = 0;
  7188. getEnvStrings().forEach(function(string, i) {
  7189. var ptr = environ_buf + bufSize;
  7190. HEAPU32[(((__environ)+(i*4))>>2)] = ptr;
  7191. writeAsciiToMemory(string, ptr);
  7192. bufSize += string.length + 1;
  7193. });
  7194. return 0;
  7195. }
  7196. function _environ_sizes_get(penviron_count, penviron_buf_size) {
  7197. var strings = getEnvStrings();
  7198. HEAPU32[((penviron_count)>>2)] = strings.length;
  7199. var bufSize = 0;
  7200. strings.forEach(function(string) {
  7201. bufSize += string.length + 1;
  7202. });
  7203. HEAPU32[((penviron_buf_size)>>2)] = bufSize;
  7204. return 0;
  7205. }
  7206. function _fd_close(fd) {
  7207. try {
  7208. var stream = SYSCALLS.getStreamFromFD(fd);
  7209. FS.close(stream);
  7210. return 0;
  7211. } catch (e) {
  7212. if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
  7213. return e.errno;
  7214. }
  7215. }
  7216. /** @param {number=} offset */
  7217. function doReadv(stream, iov, iovcnt, offset) {
  7218. var ret = 0;
  7219. for (var i = 0; i < iovcnt; i++) {
  7220. var ptr = HEAPU32[((iov)>>2)];
  7221. var len = HEAPU32[(((iov)+(4))>>2)];
  7222. iov += 8;
  7223. var curr = FS.read(stream, HEAP8,ptr, len, offset);
  7224. if (curr < 0) return -1;
  7225. ret += curr;
  7226. if (curr < len) break; // nothing more to read
  7227. }
  7228. return ret;
  7229. }
  7230. function _fd_read(fd, iov, iovcnt, pnum) {
  7231. try {
  7232. var stream = SYSCALLS.getStreamFromFD(fd);
  7233. var num = doReadv(stream, iov, iovcnt);
  7234. HEAPU32[((pnum)>>2)] = num;
  7235. return 0;
  7236. } catch (e) {
  7237. if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
  7238. return e.errno;
  7239. }
  7240. }
  7241. var MAX_INT53 = 9007199254740992;
  7242. var MIN_INT53 = -9007199254740992;
  7243. function bigintToI53Checked(num) {
  7244. return (num < MIN_INT53 || num > MAX_INT53) ? NaN : Number(num);
  7245. }
  7246. function _fd_seek(fd, /** @type {!BigInt} */ offset, whence, newOffset) {
  7247. try {
  7248. offset = bigintToI53Checked(offset); if (isNaN(offset)) return 61;
  7249. var stream = SYSCALLS.getStreamFromFD(fd);
  7250. FS.llseek(stream, offset, whence);
  7251. (tempI64 = [stream.position>>>0,(tempDouble=stream.position,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[((newOffset)>>2)] = tempI64[0],HEAP32[(((newOffset)+(4))>>2)] = tempI64[1]);
  7252. if (stream.getdents && offset === 0 && whence === 0) stream.getdents = null; // reset readdir state
  7253. return 0;
  7254. } catch (e) {
  7255. if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
  7256. return e.errno;
  7257. }
  7258. }
  7259. /** @param {number=} offset */
  7260. function doWritev(stream, iov, iovcnt, offset) {
  7261. var ret = 0;
  7262. for (var i = 0; i < iovcnt; i++) {
  7263. var ptr = HEAPU32[((iov)>>2)];
  7264. var len = HEAPU32[(((iov)+(4))>>2)];
  7265. iov += 8;
  7266. var curr = FS.write(stream, HEAP8,ptr, len, offset);
  7267. if (curr < 0) return -1;
  7268. ret += curr;
  7269. }
  7270. return ret;
  7271. }
  7272. function _fd_write(fd, iov, iovcnt, pnum) {
  7273. try {
  7274. var stream = SYSCALLS.getStreamFromFD(fd);
  7275. var num = doWritev(stream, iov, iovcnt);
  7276. HEAPU32[((pnum)>>2)] = num;
  7277. return 0;
  7278. } catch (e) {
  7279. if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e;
  7280. return e.errno;
  7281. }
  7282. }
  7283. function allocateUTF8OnStack(str) {
  7284. var size = lengthBytesUTF8(str) + 1;
  7285. var ret = stackAlloc(size);
  7286. stringToUTF8Array(str, HEAP8, ret, size);
  7287. return ret;
  7288. }
  7289. function runAndAbortIfError(func) {
  7290. try {
  7291. return func();
  7292. } catch (e) {
  7293. abort(e);
  7294. }
  7295. }
  7296. function sigToWasmTypes(sig) {
  7297. var typeNames = {
  7298. 'i': 'i32',
  7299. // i64 values will be split into two i32s.
  7300. 'j': 'i32',
  7301. 'f': 'f32',
  7302. 'd': 'f64',
  7303. 'p': 'i32',
  7304. };
  7305. var type = {
  7306. parameters: [],
  7307. results: sig[0] == 'v' ? [] : [typeNames[sig[0]]]
  7308. };
  7309. for (var i = 1; i < sig.length; ++i) {
  7310. assert(sig[i] in typeNames, 'invalid signature char: ' + sig[i]);
  7311. type.parameters.push(typeNames[sig[i]]);
  7312. if (sig[i] === 'j') {
  7313. type.parameters.push('i32');
  7314. }
  7315. }
  7316. return type;
  7317. }
  7318. var Asyncify = {instrumentWasmImports:function(imports) {
  7319. var ASYNCIFY_IMPORTS = ["env.invoke_*","env.emscripten_sleep","env.emscripten_wget","env.emscripten_wget_data","env.emscripten_idb_load","env.emscripten_idb_store","env.emscripten_idb_delete","env.emscripten_idb_exists","env.emscripten_idb_load_blob","env.emscripten_idb_store_blob","env.SDL_Delay","env.emscripten_scan_registers","env.emscripten_lazy_load_code","env.emscripten_fiber_swap","wasi_snapshot_preview1.fd_sync","env.__wasi_fd_sync","env._emval_await","env._dlopen_js","env.__asyncjs__*"].map((x) => x.split('.')[1]);
  7320. for (var x in imports) {
  7321. (function(x) {
  7322. var original = imports[x];
  7323. var sig = original.sig;
  7324. if (typeof original == 'function') {
  7325. var isAsyncifyImport = ASYNCIFY_IMPORTS.indexOf(x) >= 0 ||
  7326. x.startsWith('__asyncjs__');
  7327. imports[x] = function() {
  7328. var originalAsyncifyState = Asyncify.state;
  7329. try {
  7330. return original.apply(null, arguments);
  7331. } finally {
  7332. // Only asyncify-declared imports are allowed to change the
  7333. // state.
  7334. // Changing the state from normal to disabled is allowed (in any
  7335. // function) as that is what shutdown does (and we don't have an
  7336. // explicit list of shutdown imports).
  7337. var changedToDisabled =
  7338. originalAsyncifyState === Asyncify.State.Normal &&
  7339. Asyncify.state === Asyncify.State.Disabled;
  7340. // invoke_* functions are allowed to change the state if we do
  7341. // not ignore indirect calls.
  7342. var ignoredInvoke = x.startsWith('invoke_') &&
  7343. true;
  7344. if (Asyncify.state !== originalAsyncifyState &&
  7345. !isAsyncifyImport &&
  7346. !changedToDisabled &&
  7347. !ignoredInvoke) {
  7348. throw new Error('import ' + x + ' was not in ASYNCIFY_IMPORTS, but changed the state');
  7349. }
  7350. }
  7351. };
  7352. }
  7353. })(x);
  7354. }
  7355. },instrumentWasmExports:function(exports) {
  7356. var ret = {};
  7357. for (var x in exports) {
  7358. (function(x) {
  7359. var original = exports[x];
  7360. if (typeof original == 'function') {
  7361. ret[x] = function() {
  7362. Asyncify.exportCallStack.push(x);
  7363. try {
  7364. return original.apply(null, arguments);
  7365. } finally {
  7366. if (!ABORT) {
  7367. var y = Asyncify.exportCallStack.pop();
  7368. assert(y === x);
  7369. Asyncify.maybeStopUnwind();
  7370. }
  7371. }
  7372. };
  7373. } else {
  7374. ret[x] = original;
  7375. }
  7376. })(x);
  7377. }
  7378. return ret;
  7379. },State:{Normal:0,Unwinding:1,Rewinding:2,Disabled:3},state:0,StackSize:4096,currData:null,handleSleepReturnValue:0,exportCallStack:[],callStackNameToId:{},callStackIdToName:{},callStackId:0,asyncPromiseHandlers:null,sleepCallbacks:[],getCallStackId:function(funcName) {
  7380. var id = Asyncify.callStackNameToId[funcName];
  7381. if (id === undefined) {
  7382. id = Asyncify.callStackId++;
  7383. Asyncify.callStackNameToId[funcName] = id;
  7384. Asyncify.callStackIdToName[id] = funcName;
  7385. }
  7386. return id;
  7387. },maybeStopUnwind:function() {
  7388. if (Asyncify.currData &&
  7389. Asyncify.state === Asyncify.State.Unwinding &&
  7390. Asyncify.exportCallStack.length === 0) {
  7391. // We just finished unwinding.
  7392. // Be sure to set the state before calling any other functions to avoid
  7393. // possible infinite recursion here (For example in debug pthread builds
  7394. // the dbg() function itself can call back into WebAssembly to get the
  7395. // current pthread_self() pointer).
  7396. Asyncify.state = Asyncify.State.Normal;
  7397. runtimeKeepalivePush();
  7398. // Keep the runtime alive so that a re-wind can be done later.
  7399. runAndAbortIfError(_asyncify_stop_unwind);
  7400. if (typeof Fibers != 'undefined') {
  7401. Fibers.trampoline();
  7402. }
  7403. }
  7404. },whenDone:function() {
  7405. assert(Asyncify.currData, 'Tried to wait for an async operation when none is in progress.');
  7406. assert(!Asyncify.asyncPromiseHandlers, 'Cannot have multiple async operations in flight at once');
  7407. return new Promise((resolve, reject) => {
  7408. Asyncify.asyncPromiseHandlers = {
  7409. resolve: resolve,
  7410. reject: reject
  7411. };
  7412. });
  7413. },allocateData:function() {
  7414. // An asyncify data structure has three fields:
  7415. // 0 current stack pos
  7416. // 4 max stack pos
  7417. // 8 id of function at bottom of the call stack (callStackIdToName[id] == name of js function)
  7418. //
  7419. // The Asyncify ABI only interprets the first two fields, the rest is for the runtime.
  7420. // We also embed a stack in the same memory region here, right next to the structure.
  7421. // This struct is also defined as asyncify_data_t in emscripten/fiber.h
  7422. var ptr = _malloc(12 + Asyncify.StackSize);
  7423. Asyncify.setDataHeader(ptr, ptr + 12, Asyncify.StackSize);
  7424. Asyncify.setDataRewindFunc(ptr);
  7425. return ptr;
  7426. },setDataHeader:function(ptr, stack, stackSize) {
  7427. HEAP32[((ptr)>>2)] = stack;
  7428. HEAP32[(((ptr)+(4))>>2)] = stack + stackSize;
  7429. },setDataRewindFunc:function(ptr) {
  7430. var bottomOfCallStack = Asyncify.exportCallStack[0];
  7431. var rewindId = Asyncify.getCallStackId(bottomOfCallStack);
  7432. HEAP32[(((ptr)+(8))>>2)] = rewindId;
  7433. },getDataRewindFunc:function(ptr) {
  7434. var id = HEAP32[(((ptr)+(8))>>2)];
  7435. var name = Asyncify.callStackIdToName[id];
  7436. var func = Module['asm'][name];
  7437. return func;
  7438. },doRewind:function(ptr) {
  7439. var start = Asyncify.getDataRewindFunc(ptr);
  7440. // Once we have rewound and the stack we no longer need to artificially
  7441. // keep the runtime alive.
  7442. runtimeKeepalivePop();
  7443. return start();
  7444. },handleSleep:function(startAsync) {
  7445. assert(Asyncify.state !== Asyncify.State.Disabled, 'Asyncify cannot be done during or after the runtime exits');
  7446. if (ABORT) return;
  7447. if (Asyncify.state === Asyncify.State.Normal) {
  7448. // Prepare to sleep. Call startAsync, and see what happens:
  7449. // if the code decided to call our callback synchronously,
  7450. // then no async operation was in fact begun, and we don't
  7451. // need to do anything.
  7452. var reachedCallback = false;
  7453. var reachedAfterCallback = false;
  7454. startAsync((handleSleepReturnValue) => {
  7455. assert(!handleSleepReturnValue || typeof handleSleepReturnValue == 'number' || typeof handleSleepReturnValue == 'boolean'); // old emterpretify API supported other stuff
  7456. if (ABORT) return;
  7457. Asyncify.handleSleepReturnValue = handleSleepReturnValue || 0;
  7458. reachedCallback = true;
  7459. if (!reachedAfterCallback) {
  7460. // We are happening synchronously, so no need for async.
  7461. return;
  7462. }
  7463. // This async operation did not happen synchronously, so we did
  7464. // unwind. In that case there can be no compiled code on the stack,
  7465. // as it might break later operations (we can rewind ok now, but if
  7466. // we unwind again, we would unwind through the extra compiled code
  7467. // too).
  7468. assert(!Asyncify.exportCallStack.length, 'Waking up (starting to rewind) must be done from JS, without compiled code on the stack.');
  7469. Asyncify.state = Asyncify.State.Rewinding;
  7470. runAndAbortIfError(() => _asyncify_start_rewind(Asyncify.currData));
  7471. if (typeof Browser != 'undefined' && Browser.mainLoop.func) {
  7472. Browser.mainLoop.resume();
  7473. }
  7474. var asyncWasmReturnValue, isError = false;
  7475. try {
  7476. asyncWasmReturnValue = Asyncify.doRewind(Asyncify.currData);
  7477. } catch (err) {
  7478. asyncWasmReturnValue = err;
  7479. isError = true;
  7480. }
  7481. // Track whether the return value was handled by any promise handlers.
  7482. var handled = false;
  7483. if (!Asyncify.currData) {
  7484. // All asynchronous execution has finished.
  7485. // `asyncWasmReturnValue` now contains the final
  7486. // return value of the exported async WASM function.
  7487. //
  7488. // Note: `asyncWasmReturnValue` is distinct from
  7489. // `Asyncify.handleSleepReturnValue`.
  7490. // `Asyncify.handleSleepReturnValue` contains the return
  7491. // value of the last C function to have executed
  7492. // `Asyncify.handleSleep()`, where as `asyncWasmReturnValue`
  7493. // contains the return value of the exported WASM function
  7494. // that may have called C functions that
  7495. // call `Asyncify.handleSleep()`.
  7496. var asyncPromiseHandlers = Asyncify.asyncPromiseHandlers;
  7497. if (asyncPromiseHandlers) {
  7498. Asyncify.asyncPromiseHandlers = null;
  7499. (isError ? asyncPromiseHandlers.reject : asyncPromiseHandlers.resolve)(asyncWasmReturnValue);
  7500. handled = true;
  7501. }
  7502. }
  7503. if (isError && !handled) {
  7504. // If there was an error and it was not handled by now, we have no choice but to
  7505. // rethrow that error into the global scope where it can be caught only by
  7506. // `onerror` or `onunhandledpromiserejection`.
  7507. throw asyncWasmReturnValue;
  7508. }
  7509. });
  7510. reachedAfterCallback = true;
  7511. if (!reachedCallback) {
  7512. // A true async operation was begun; start a sleep.
  7513. Asyncify.state = Asyncify.State.Unwinding;
  7514. // TODO: reuse, don't alloc/free every sleep
  7515. Asyncify.currData = Asyncify.allocateData();
  7516. if (typeof Browser != 'undefined' && Browser.mainLoop.func) {
  7517. Browser.mainLoop.pause();
  7518. }
  7519. runAndAbortIfError(() => _asyncify_start_unwind(Asyncify.currData));
  7520. }
  7521. } else if (Asyncify.state === Asyncify.State.Rewinding) {
  7522. // Stop a resume.
  7523. Asyncify.state = Asyncify.State.Normal;
  7524. runAndAbortIfError(_asyncify_stop_rewind);
  7525. _free(Asyncify.currData);
  7526. Asyncify.currData = null;
  7527. // Call all sleep callbacks now that the sleep-resume is all done.
  7528. Asyncify.sleepCallbacks.forEach((func) => callUserCallback(func));
  7529. } else {
  7530. abort('invalid state: ' + Asyncify.state);
  7531. }
  7532. return Asyncify.handleSleepReturnValue;
  7533. },handleAsync:function(startAsync) {
  7534. return Asyncify.handleSleep((wakeUp) => {
  7535. // TODO: add error handling as a second param when handleSleep implements it.
  7536. startAsync().then(wakeUp);
  7537. });
  7538. }};
  7539. var FSNode = /** @constructor */ function(parent, name, mode, rdev) {
  7540. if (!parent) {
  7541. parent = this; // root node sets parent to itself
  7542. }
  7543. this.parent = parent;
  7544. this.mount = parent.mount;
  7545. this.mounted = null;
  7546. this.id = FS.nextInode++;
  7547. this.name = name;
  7548. this.mode = mode;
  7549. this.node_ops = {};
  7550. this.stream_ops = {};
  7551. this.rdev = rdev;
  7552. };
  7553. var readMode = 292/*292*/ | 73/*73*/;
  7554. var writeMode = 146/*146*/;
  7555. Object.defineProperties(FSNode.prototype, {
  7556. read: {
  7557. get: /** @this{FSNode} */function() {
  7558. return (this.mode & readMode) === readMode;
  7559. },
  7560. set: /** @this{FSNode} */function(val) {
  7561. val ? this.mode |= readMode : this.mode &= ~readMode;
  7562. }
  7563. },
  7564. write: {
  7565. get: /** @this{FSNode} */function() {
  7566. return (this.mode & writeMode) === writeMode;
  7567. },
  7568. set: /** @this{FSNode} */function(val) {
  7569. val ? this.mode |= writeMode : this.mode &= ~writeMode;
  7570. }
  7571. },
  7572. isFolder: {
  7573. get: /** @this{FSNode} */function() {
  7574. return FS.isDir(this.mode);
  7575. }
  7576. },
  7577. isDevice: {
  7578. get: /** @this{FSNode} */function() {
  7579. return FS.isChrdev(this.mode);
  7580. }
  7581. }
  7582. });
  7583. FS.FSNode = FSNode;
  7584. FS.staticInit();;
  7585. ERRNO_CODES = {
  7586. 'EPERM': 63,
  7587. 'ENOENT': 44,
  7588. 'ESRCH': 71,
  7589. 'EINTR': 27,
  7590. 'EIO': 29,
  7591. 'ENXIO': 60,
  7592. 'E2BIG': 1,
  7593. 'ENOEXEC': 45,
  7594. 'EBADF': 8,
  7595. 'ECHILD': 12,
  7596. 'EAGAIN': 6,
  7597. 'EWOULDBLOCK': 6,
  7598. 'ENOMEM': 48,
  7599. 'EACCES': 2,
  7600. 'EFAULT': 21,
  7601. 'ENOTBLK': 105,
  7602. 'EBUSY': 10,
  7603. 'EEXIST': 20,
  7604. 'EXDEV': 75,
  7605. 'ENODEV': 43,
  7606. 'ENOTDIR': 54,
  7607. 'EISDIR': 31,
  7608. 'EINVAL': 28,
  7609. 'ENFILE': 41,
  7610. 'EMFILE': 33,
  7611. 'ENOTTY': 59,
  7612. 'ETXTBSY': 74,
  7613. 'EFBIG': 22,
  7614. 'ENOSPC': 51,
  7615. 'ESPIPE': 70,
  7616. 'EROFS': 69,
  7617. 'EMLINK': 34,
  7618. 'EPIPE': 64,
  7619. 'EDOM': 18,
  7620. 'ERANGE': 68,
  7621. 'ENOMSG': 49,
  7622. 'EIDRM': 24,
  7623. 'ECHRNG': 106,
  7624. 'EL2NSYNC': 156,
  7625. 'EL3HLT': 107,
  7626. 'EL3RST': 108,
  7627. 'ELNRNG': 109,
  7628. 'EUNATCH': 110,
  7629. 'ENOCSI': 111,
  7630. 'EL2HLT': 112,
  7631. 'EDEADLK': 16,
  7632. 'ENOLCK': 46,
  7633. 'EBADE': 113,
  7634. 'EBADR': 114,
  7635. 'EXFULL': 115,
  7636. 'ENOANO': 104,
  7637. 'EBADRQC': 103,
  7638. 'EBADSLT': 102,
  7639. 'EDEADLOCK': 16,
  7640. 'EBFONT': 101,
  7641. 'ENOSTR': 100,
  7642. 'ENODATA': 116,
  7643. 'ETIME': 117,
  7644. 'ENOSR': 118,
  7645. 'ENONET': 119,
  7646. 'ENOPKG': 120,
  7647. 'EREMOTE': 121,
  7648. 'ENOLINK': 47,
  7649. 'EADV': 122,
  7650. 'ESRMNT': 123,
  7651. 'ECOMM': 124,
  7652. 'EPROTO': 65,
  7653. 'EMULTIHOP': 36,
  7654. 'EDOTDOT': 125,
  7655. 'EBADMSG': 9,
  7656. 'ENOTUNIQ': 126,
  7657. 'EBADFD': 127,
  7658. 'EREMCHG': 128,
  7659. 'ELIBACC': 129,
  7660. 'ELIBBAD': 130,
  7661. 'ELIBSCN': 131,
  7662. 'ELIBMAX': 132,
  7663. 'ELIBEXEC': 133,
  7664. 'ENOSYS': 52,
  7665. 'ENOTEMPTY': 55,
  7666. 'ENAMETOOLONG': 37,
  7667. 'ELOOP': 32,
  7668. 'EOPNOTSUPP': 138,
  7669. 'EPFNOSUPPORT': 139,
  7670. 'ECONNRESET': 15,
  7671. 'ENOBUFS': 42,
  7672. 'EAFNOSUPPORT': 5,
  7673. 'EPROTOTYPE': 67,
  7674. 'ENOTSOCK': 57,
  7675. 'ENOPROTOOPT': 50,
  7676. 'ESHUTDOWN': 140,
  7677. 'ECONNREFUSED': 14,
  7678. 'EADDRINUSE': 3,
  7679. 'ECONNABORTED': 13,
  7680. 'ENETUNREACH': 40,
  7681. 'ENETDOWN': 38,
  7682. 'ETIMEDOUT': 73,
  7683. 'EHOSTDOWN': 142,
  7684. 'EHOSTUNREACH': 23,
  7685. 'EINPROGRESS': 26,
  7686. 'EALREADY': 7,
  7687. 'EDESTADDRREQ': 17,
  7688. 'EMSGSIZE': 35,
  7689. 'EPROTONOSUPPORT': 66,
  7690. 'ESOCKTNOSUPPORT': 137,
  7691. 'EADDRNOTAVAIL': 4,
  7692. 'ENETRESET': 39,
  7693. 'EISCONN': 30,
  7694. 'ENOTCONN': 53,
  7695. 'ETOOMANYREFS': 141,
  7696. 'EUSERS': 136,
  7697. 'EDQUOT': 19,
  7698. 'ESTALE': 72,
  7699. 'ENOTSUP': 138,
  7700. 'ENOMEDIUM': 148,
  7701. 'EILSEQ': 25,
  7702. 'EOVERFLOW': 61,
  7703. 'ECANCELED': 11,
  7704. 'ENOTRECOVERABLE': 56,
  7705. 'EOWNERDEAD': 62,
  7706. 'ESTRPIPE': 135,
  7707. };;
  7708. // exports
  7709. Module["requestFullscreen"] = function Module_requestFullscreen(lockPointer, resizeCanvas) { Browser.requestFullscreen(lockPointer, resizeCanvas) };
  7710. Module["requestFullScreen"] = function Module_requestFullScreen() { Browser.requestFullScreen() };
  7711. Module["requestAnimationFrame"] = function Module_requestAnimationFrame(func) { Browser.requestAnimationFrame(func) };
  7712. Module["setCanvasSize"] = function Module_setCanvasSize(width, height, noUpdates) { Browser.setCanvasSize(width, height, noUpdates) };
  7713. Module["pauseMainLoop"] = function Module_pauseMainLoop() { Browser.mainLoop.pause() };
  7714. Module["resumeMainLoop"] = function Module_resumeMainLoop() { Browser.mainLoop.resume() };
  7715. Module["getUserMedia"] = function Module_getUserMedia() { Browser.getUserMedia() };
  7716. Module["createContext"] = function Module_createContext(canvas, useWebGL, setInModule, webGLContextAttributes) { return Browser.createContext(canvas, useWebGL, setInModule, webGLContextAttributes) };
  7717. var preloadedImages = {};
  7718. var preloadedAudios = {};;
  7719. var GLctx;;
  7720. for (var i = 0; i < 32; ++i) tempFixedLengthArray.push(new Array(i));;
  7721. var miniTempWebGLFloatBuffersStorage = new Float32Array(288);
  7722. for (/**@suppress{duplicate}*/var i = 0; i < 288; ++i) {
  7723. miniTempWebGLFloatBuffers[i] = miniTempWebGLFloatBuffersStorage.subarray(0, i+1);
  7724. }
  7725. ;
  7726. var __miniTempWebGLIntBuffersStorage = new Int32Array(288);
  7727. for (/**@suppress{duplicate}*/var i = 0; i < 288; ++i) {
  7728. __miniTempWebGLIntBuffers[i] = __miniTempWebGLIntBuffersStorage.subarray(0, i+1);
  7729. }
  7730. ;
  7731. var ASSERTIONS = true;
  7732. function checkIncomingModuleAPI() {
  7733. ignoredModuleProp('fetchSettings');
  7734. }
  7735. var asmLibraryArg = {
  7736. "__assert_fail": ___assert_fail,
  7737. "__asyncjs__emscriptmadness": __asyncjs__emscriptmadness,
  7738. "__syscall_fcntl64": ___syscall_fcntl64,
  7739. "__syscall_ioctl": ___syscall_ioctl,
  7740. "__syscall_openat": ___syscall_openat,
  7741. "_emscripten_get_now_is_monotonic": __emscripten_get_now_is_monotonic,
  7742. "eglBindAPI": _eglBindAPI,
  7743. "eglChooseConfig": _eglChooseConfig,
  7744. "eglCreateContext": _eglCreateContext,
  7745. "eglCreateWindowSurface": _eglCreateWindowSurface,
  7746. "eglDestroyContext": _eglDestroyContext,
  7747. "eglDestroySurface": _eglDestroySurface,
  7748. "eglGetConfigAttrib": _eglGetConfigAttrib,
  7749. "eglGetDisplay": _eglGetDisplay,
  7750. "eglGetError": _eglGetError,
  7751. "eglInitialize": _eglInitialize,
  7752. "eglMakeCurrent": _eglMakeCurrent,
  7753. "eglQueryString": _eglQueryString,
  7754. "eglSwapBuffers": _eglSwapBuffers,
  7755. "eglSwapInterval": _eglSwapInterval,
  7756. "eglTerminate": _eglTerminate,
  7757. "eglWaitGL": _eglWaitGL,
  7758. "eglWaitNative": _eglWaitNative,
  7759. "emscripten_asm_const_int": _emscripten_asm_const_int,
  7760. "emscripten_asm_const_int_sync_on_main_thread": _emscripten_asm_const_int_sync_on_main_thread,
  7761. "emscripten_cancel_main_loop": _emscripten_cancel_main_loop,
  7762. "emscripten_date_now": _emscripten_date_now,
  7763. "emscripten_exit_fullscreen": _emscripten_exit_fullscreen,
  7764. "emscripten_exit_pointerlock": _emscripten_exit_pointerlock,
  7765. "emscripten_get_device_pixel_ratio": _emscripten_get_device_pixel_ratio,
  7766. "emscripten_get_element_css_size": _emscripten_get_element_css_size,
  7767. "emscripten_get_gamepad_status": _emscripten_get_gamepad_status,
  7768. "emscripten_get_now": _emscripten_get_now,
  7769. "emscripten_get_num_gamepads": _emscripten_get_num_gamepads,
  7770. "emscripten_get_screen_size": _emscripten_get_screen_size,
  7771. "emscripten_glActiveTexture": _emscripten_glActiveTexture,
  7772. "emscripten_glAttachShader": _emscripten_glAttachShader,
  7773. "emscripten_glBeginQueryEXT": _emscripten_glBeginQueryEXT,
  7774. "emscripten_glBindAttribLocation": _emscripten_glBindAttribLocation,
  7775. "emscripten_glBindBuffer": _emscripten_glBindBuffer,
  7776. "emscripten_glBindFramebuffer": _emscripten_glBindFramebuffer,
  7777. "emscripten_glBindRenderbuffer": _emscripten_glBindRenderbuffer,
  7778. "emscripten_glBindTexture": _emscripten_glBindTexture,
  7779. "emscripten_glBindVertexArrayOES": _emscripten_glBindVertexArrayOES,
  7780. "emscripten_glBlendColor": _emscripten_glBlendColor,
  7781. "emscripten_glBlendEquation": _emscripten_glBlendEquation,
  7782. "emscripten_glBlendEquationSeparate": _emscripten_glBlendEquationSeparate,
  7783. "emscripten_glBlendFunc": _emscripten_glBlendFunc,
  7784. "emscripten_glBlendFuncSeparate": _emscripten_glBlendFuncSeparate,
  7785. "emscripten_glBufferData": _emscripten_glBufferData,
  7786. "emscripten_glBufferSubData": _emscripten_glBufferSubData,
  7787. "emscripten_glCheckFramebufferStatus": _emscripten_glCheckFramebufferStatus,
  7788. "emscripten_glClear": _emscripten_glClear,
  7789. "emscripten_glClearColor": _emscripten_glClearColor,
  7790. "emscripten_glClearDepthf": _emscripten_glClearDepthf,
  7791. "emscripten_glClearStencil": _emscripten_glClearStencil,
  7792. "emscripten_glColorMask": _emscripten_glColorMask,
  7793. "emscripten_glCompileShader": _emscripten_glCompileShader,
  7794. "emscripten_glCompressedTexImage2D": _emscripten_glCompressedTexImage2D,
  7795. "emscripten_glCompressedTexSubImage2D": _emscripten_glCompressedTexSubImage2D,
  7796. "emscripten_glCopyTexImage2D": _emscripten_glCopyTexImage2D,
  7797. "emscripten_glCopyTexSubImage2D": _emscripten_glCopyTexSubImage2D,
  7798. "emscripten_glCreateProgram": _emscripten_glCreateProgram,
  7799. "emscripten_glCreateShader": _emscripten_glCreateShader,
  7800. "emscripten_glCullFace": _emscripten_glCullFace,
  7801. "emscripten_glDeleteBuffers": _emscripten_glDeleteBuffers,
  7802. "emscripten_glDeleteFramebuffers": _emscripten_glDeleteFramebuffers,
  7803. "emscripten_glDeleteProgram": _emscripten_glDeleteProgram,
  7804. "emscripten_glDeleteQueriesEXT": _emscripten_glDeleteQueriesEXT,
  7805. "emscripten_glDeleteRenderbuffers": _emscripten_glDeleteRenderbuffers,
  7806. "emscripten_glDeleteShader": _emscripten_glDeleteShader,
  7807. "emscripten_glDeleteTextures": _emscripten_glDeleteTextures,
  7808. "emscripten_glDeleteVertexArraysOES": _emscripten_glDeleteVertexArraysOES,
  7809. "emscripten_glDepthFunc": _emscripten_glDepthFunc,
  7810. "emscripten_glDepthMask": _emscripten_glDepthMask,
  7811. "emscripten_glDepthRangef": _emscripten_glDepthRangef,
  7812. "emscripten_glDetachShader": _emscripten_glDetachShader,
  7813. "emscripten_glDisable": _emscripten_glDisable,
  7814. "emscripten_glDisableVertexAttribArray": _emscripten_glDisableVertexAttribArray,
  7815. "emscripten_glDrawArrays": _emscripten_glDrawArrays,
  7816. "emscripten_glDrawArraysInstancedANGLE": _emscripten_glDrawArraysInstancedANGLE,
  7817. "emscripten_glDrawBuffersWEBGL": _emscripten_glDrawBuffersWEBGL,
  7818. "emscripten_glDrawElements": _emscripten_glDrawElements,
  7819. "emscripten_glDrawElementsInstancedANGLE": _emscripten_glDrawElementsInstancedANGLE,
  7820. "emscripten_glEnable": _emscripten_glEnable,
  7821. "emscripten_glEnableVertexAttribArray": _emscripten_glEnableVertexAttribArray,
  7822. "emscripten_glEndQueryEXT": _emscripten_glEndQueryEXT,
  7823. "emscripten_glFinish": _emscripten_glFinish,
  7824. "emscripten_glFlush": _emscripten_glFlush,
  7825. "emscripten_glFramebufferRenderbuffer": _emscripten_glFramebufferRenderbuffer,
  7826. "emscripten_glFramebufferTexture2D": _emscripten_glFramebufferTexture2D,
  7827. "emscripten_glFrontFace": _emscripten_glFrontFace,
  7828. "emscripten_glGenBuffers": _emscripten_glGenBuffers,
  7829. "emscripten_glGenFramebuffers": _emscripten_glGenFramebuffers,
  7830. "emscripten_glGenQueriesEXT": _emscripten_glGenQueriesEXT,
  7831. "emscripten_glGenRenderbuffers": _emscripten_glGenRenderbuffers,
  7832. "emscripten_glGenTextures": _emscripten_glGenTextures,
  7833. "emscripten_glGenVertexArraysOES": _emscripten_glGenVertexArraysOES,
  7834. "emscripten_glGenerateMipmap": _emscripten_glGenerateMipmap,
  7835. "emscripten_glGetActiveAttrib": _emscripten_glGetActiveAttrib,
  7836. "emscripten_glGetActiveUniform": _emscripten_glGetActiveUniform,
  7837. "emscripten_glGetAttachedShaders": _emscripten_glGetAttachedShaders,
  7838. "emscripten_glGetAttribLocation": _emscripten_glGetAttribLocation,
  7839. "emscripten_glGetBooleanv": _emscripten_glGetBooleanv,
  7840. "emscripten_glGetBufferParameteriv": _emscripten_glGetBufferParameteriv,
  7841. "emscripten_glGetError": _emscripten_glGetError,
  7842. "emscripten_glGetFloatv": _emscripten_glGetFloatv,
  7843. "emscripten_glGetFramebufferAttachmentParameteriv": _emscripten_glGetFramebufferAttachmentParameteriv,
  7844. "emscripten_glGetIntegerv": _emscripten_glGetIntegerv,
  7845. "emscripten_glGetProgramInfoLog": _emscripten_glGetProgramInfoLog,
  7846. "emscripten_glGetProgramiv": _emscripten_glGetProgramiv,
  7847. "emscripten_glGetQueryObjecti64vEXT": _emscripten_glGetQueryObjecti64vEXT,
  7848. "emscripten_glGetQueryObjectivEXT": _emscripten_glGetQueryObjectivEXT,
  7849. "emscripten_glGetQueryObjectui64vEXT": _emscripten_glGetQueryObjectui64vEXT,
  7850. "emscripten_glGetQueryObjectuivEXT": _emscripten_glGetQueryObjectuivEXT,
  7851. "emscripten_glGetQueryivEXT": _emscripten_glGetQueryivEXT,
  7852. "emscripten_glGetRenderbufferParameteriv": _emscripten_glGetRenderbufferParameteriv,
  7853. "emscripten_glGetShaderInfoLog": _emscripten_glGetShaderInfoLog,
  7854. "emscripten_glGetShaderPrecisionFormat": _emscripten_glGetShaderPrecisionFormat,
  7855. "emscripten_glGetShaderSource": _emscripten_glGetShaderSource,
  7856. "emscripten_glGetShaderiv": _emscripten_glGetShaderiv,
  7857. "emscripten_glGetString": _emscripten_glGetString,
  7858. "emscripten_glGetTexParameterfv": _emscripten_glGetTexParameterfv,
  7859. "emscripten_glGetTexParameteriv": _emscripten_glGetTexParameteriv,
  7860. "emscripten_glGetUniformLocation": _emscripten_glGetUniformLocation,
  7861. "emscripten_glGetUniformfv": _emscripten_glGetUniformfv,
  7862. "emscripten_glGetUniformiv": _emscripten_glGetUniformiv,
  7863. "emscripten_glGetVertexAttribPointerv": _emscripten_glGetVertexAttribPointerv,
  7864. "emscripten_glGetVertexAttribfv": _emscripten_glGetVertexAttribfv,
  7865. "emscripten_glGetVertexAttribiv": _emscripten_glGetVertexAttribiv,
  7866. "emscripten_glHint": _emscripten_glHint,
  7867. "emscripten_glIsBuffer": _emscripten_glIsBuffer,
  7868. "emscripten_glIsEnabled": _emscripten_glIsEnabled,
  7869. "emscripten_glIsFramebuffer": _emscripten_glIsFramebuffer,
  7870. "emscripten_glIsProgram": _emscripten_glIsProgram,
  7871. "emscripten_glIsQueryEXT": _emscripten_glIsQueryEXT,
  7872. "emscripten_glIsRenderbuffer": _emscripten_glIsRenderbuffer,
  7873. "emscripten_glIsShader": _emscripten_glIsShader,
  7874. "emscripten_glIsTexture": _emscripten_glIsTexture,
  7875. "emscripten_glIsVertexArrayOES": _emscripten_glIsVertexArrayOES,
  7876. "emscripten_glLineWidth": _emscripten_glLineWidth,
  7877. "emscripten_glLinkProgram": _emscripten_glLinkProgram,
  7878. "emscripten_glPixelStorei": _emscripten_glPixelStorei,
  7879. "emscripten_glPolygonOffset": _emscripten_glPolygonOffset,
  7880. "emscripten_glQueryCounterEXT": _emscripten_glQueryCounterEXT,
  7881. "emscripten_glReadPixels": _emscripten_glReadPixels,
  7882. "emscripten_glReleaseShaderCompiler": _emscripten_glReleaseShaderCompiler,
  7883. "emscripten_glRenderbufferStorage": _emscripten_glRenderbufferStorage,
  7884. "emscripten_glSampleCoverage": _emscripten_glSampleCoverage,
  7885. "emscripten_glScissor": _emscripten_glScissor,
  7886. "emscripten_glShaderBinary": _emscripten_glShaderBinary,
  7887. "emscripten_glShaderSource": _emscripten_glShaderSource,
  7888. "emscripten_glStencilFunc": _emscripten_glStencilFunc,
  7889. "emscripten_glStencilFuncSeparate": _emscripten_glStencilFuncSeparate,
  7890. "emscripten_glStencilMask": _emscripten_glStencilMask,
  7891. "emscripten_glStencilMaskSeparate": _emscripten_glStencilMaskSeparate,
  7892. "emscripten_glStencilOp": _emscripten_glStencilOp,
  7893. "emscripten_glStencilOpSeparate": _emscripten_glStencilOpSeparate,
  7894. "emscripten_glTexImage2D": _emscripten_glTexImage2D,
  7895. "emscripten_glTexParameterf": _emscripten_glTexParameterf,
  7896. "emscripten_glTexParameterfv": _emscripten_glTexParameterfv,
  7897. "emscripten_glTexParameteri": _emscripten_glTexParameteri,
  7898. "emscripten_glTexParameteriv": _emscripten_glTexParameteriv,
  7899. "emscripten_glTexSubImage2D": _emscripten_glTexSubImage2D,
  7900. "emscripten_glUniform1f": _emscripten_glUniform1f,
  7901. "emscripten_glUniform1fv": _emscripten_glUniform1fv,
  7902. "emscripten_glUniform1i": _emscripten_glUniform1i,
  7903. "emscripten_glUniform1iv": _emscripten_glUniform1iv,
  7904. "emscripten_glUniform2f": _emscripten_glUniform2f,
  7905. "emscripten_glUniform2fv": _emscripten_glUniform2fv,
  7906. "emscripten_glUniform2i": _emscripten_glUniform2i,
  7907. "emscripten_glUniform2iv": _emscripten_glUniform2iv,
  7908. "emscripten_glUniform3f": _emscripten_glUniform3f,
  7909. "emscripten_glUniform3fv": _emscripten_glUniform3fv,
  7910. "emscripten_glUniform3i": _emscripten_glUniform3i,
  7911. "emscripten_glUniform3iv": _emscripten_glUniform3iv,
  7912. "emscripten_glUniform4f": _emscripten_glUniform4f,
  7913. "emscripten_glUniform4fv": _emscripten_glUniform4fv,
  7914. "emscripten_glUniform4i": _emscripten_glUniform4i,
  7915. "emscripten_glUniform4iv": _emscripten_glUniform4iv,
  7916. "emscripten_glUniformMatrix2fv": _emscripten_glUniformMatrix2fv,
  7917. "emscripten_glUniformMatrix3fv": _emscripten_glUniformMatrix3fv,
  7918. "emscripten_glUniformMatrix4fv": _emscripten_glUniformMatrix4fv,
  7919. "emscripten_glUseProgram": _emscripten_glUseProgram,
  7920. "emscripten_glValidateProgram": _emscripten_glValidateProgram,
  7921. "emscripten_glVertexAttrib1f": _emscripten_glVertexAttrib1f,
  7922. "emscripten_glVertexAttrib1fv": _emscripten_glVertexAttrib1fv,
  7923. "emscripten_glVertexAttrib2f": _emscripten_glVertexAttrib2f,
  7924. "emscripten_glVertexAttrib2fv": _emscripten_glVertexAttrib2fv,
  7925. "emscripten_glVertexAttrib3f": _emscripten_glVertexAttrib3f,
  7926. "emscripten_glVertexAttrib3fv": _emscripten_glVertexAttrib3fv,
  7927. "emscripten_glVertexAttrib4f": _emscripten_glVertexAttrib4f,
  7928. "emscripten_glVertexAttrib4fv": _emscripten_glVertexAttrib4fv,
  7929. "emscripten_glVertexAttribDivisorANGLE": _emscripten_glVertexAttribDivisorANGLE,
  7930. "emscripten_glVertexAttribPointer": _emscripten_glVertexAttribPointer,
  7931. "emscripten_glViewport": _emscripten_glViewport,
  7932. "emscripten_has_asyncify": _emscripten_has_asyncify,
  7933. "emscripten_memcpy_big": _emscripten_memcpy_big,
  7934. "emscripten_request_fullscreen_strategy": _emscripten_request_fullscreen_strategy,
  7935. "emscripten_request_pointerlock": _emscripten_request_pointerlock,
  7936. "emscripten_resize_heap": _emscripten_resize_heap,
  7937. "emscripten_sample_gamepad_data": _emscripten_sample_gamepad_data,
  7938. "emscripten_set_beforeunload_callback_on_thread": _emscripten_set_beforeunload_callback_on_thread,
  7939. "emscripten_set_blur_callback_on_thread": _emscripten_set_blur_callback_on_thread,
  7940. "emscripten_set_canvas_element_size": _emscripten_set_canvas_element_size,
  7941. "emscripten_set_element_css_size": _emscripten_set_element_css_size,
  7942. "emscripten_set_focus_callback_on_thread": _emscripten_set_focus_callback_on_thread,
  7943. "emscripten_set_fullscreenchange_callback_on_thread": _emscripten_set_fullscreenchange_callback_on_thread,
  7944. "emscripten_set_gamepadconnected_callback_on_thread": _emscripten_set_gamepadconnected_callback_on_thread,
  7945. "emscripten_set_gamepaddisconnected_callback_on_thread": _emscripten_set_gamepaddisconnected_callback_on_thread,
  7946. "emscripten_set_keydown_callback_on_thread": _emscripten_set_keydown_callback_on_thread,
  7947. "emscripten_set_keypress_callback_on_thread": _emscripten_set_keypress_callback_on_thread,
  7948. "emscripten_set_keyup_callback_on_thread": _emscripten_set_keyup_callback_on_thread,
  7949. "emscripten_set_main_loop": _emscripten_set_main_loop,
  7950. "emscripten_set_mousedown_callback_on_thread": _emscripten_set_mousedown_callback_on_thread,
  7951. "emscripten_set_mouseenter_callback_on_thread": _emscripten_set_mouseenter_callback_on_thread,
  7952. "emscripten_set_mouseleave_callback_on_thread": _emscripten_set_mouseleave_callback_on_thread,
  7953. "emscripten_set_mousemove_callback_on_thread": _emscripten_set_mousemove_callback_on_thread,
  7954. "emscripten_set_mouseup_callback_on_thread": _emscripten_set_mouseup_callback_on_thread,
  7955. "emscripten_set_pointerlockchange_callback_on_thread": _emscripten_set_pointerlockchange_callback_on_thread,
  7956. "emscripten_set_resize_callback_on_thread": _emscripten_set_resize_callback_on_thread,
  7957. "emscripten_set_touchcancel_callback_on_thread": _emscripten_set_touchcancel_callback_on_thread,
  7958. "emscripten_set_touchend_callback_on_thread": _emscripten_set_touchend_callback_on_thread,
  7959. "emscripten_set_touchmove_callback_on_thread": _emscripten_set_touchmove_callback_on_thread,
  7960. "emscripten_set_touchstart_callback_on_thread": _emscripten_set_touchstart_callback_on_thread,
  7961. "emscripten_set_visibilitychange_callback_on_thread": _emscripten_set_visibilitychange_callback_on_thread,
  7962. "emscripten_set_wheel_callback_on_thread": _emscripten_set_wheel_callback_on_thread,
  7963. "emscripten_set_window_title": _emscripten_set_window_title,
  7964. "emscripten_sleep": _emscripten_sleep,
  7965. "environ_get": _environ_get,
  7966. "environ_sizes_get": _environ_sizes_get,
  7967. "exit": _exit,
  7968. "fd_close": _fd_close,
  7969. "fd_read": _fd_read,
  7970. "fd_seek": _fd_seek,
  7971. "fd_write": _fd_write
  7972. };
  7973. Asyncify.instrumentWasmImports(asmLibraryArg);
  7974. var asm = createWasm();
  7975. /** @type {function(...*):?} */
  7976. var ___wasm_call_ctors = Module["___wasm_call_ctors"] = createExportWrapper("__wasm_call_ctors");
  7977. /** @type {function(...*):?} */
  7978. var _memcpy = Module["_memcpy"] = createExportWrapper("memcpy");
  7979. /** @type {function(...*):?} */
  7980. var _free = Module["_free"] = createExportWrapper("free");
  7981. /** @type {function(...*):?} */
  7982. var _malloc = Module["_malloc"] = createExportWrapper("malloc");
  7983. /** @type {function(...*):?} */
  7984. var _main = Module["_main"] = createExportWrapper("__main_argc_argv");
  7985. /** @type {function(...*):?} */
  7986. var _fflush = Module["_fflush"] = createExportWrapper("fflush");
  7987. /** @type {function(...*):?} */
  7988. var ___errno_location = Module["___errno_location"] = createExportWrapper("__errno_location");
  7989. /** @type {function(...*):?} */
  7990. var ___funcs_on_exit = Module["___funcs_on_exit"] = createExportWrapper("__funcs_on_exit");
  7991. /** @type {function(...*):?} */
  7992. var ___dl_seterr = Module["___dl_seterr"] = createExportWrapper("__dl_seterr");
  7993. /** @type {function(...*):?} */
  7994. var _fileno = Module["_fileno"] = createExportWrapper("fileno");
  7995. /** @type {function(...*):?} */
  7996. var _emscripten_stack_init = Module["_emscripten_stack_init"] = function() {
  7997. return (_emscripten_stack_init = Module["_emscripten_stack_init"] = Module["asm"]["emscripten_stack_init"]).apply(null, arguments);
  7998. };
  7999. /** @type {function(...*):?} */
  8000. var _emscripten_stack_set_limits = Module["_emscripten_stack_set_limits"] = function() {
  8001. return (_emscripten_stack_set_limits = Module["_emscripten_stack_set_limits"] = Module["asm"]["emscripten_stack_set_limits"]).apply(null, arguments);
  8002. };
  8003. /** @type {function(...*):?} */
  8004. var _emscripten_stack_get_free = Module["_emscripten_stack_get_free"] = function() {
  8005. return (_emscripten_stack_get_free = Module["_emscripten_stack_get_free"] = Module["asm"]["emscripten_stack_get_free"]).apply(null, arguments);
  8006. };
  8007. /** @type {function(...*):?} */
  8008. var _emscripten_stack_get_base = Module["_emscripten_stack_get_base"] = function() {
  8009. return (_emscripten_stack_get_base = Module["_emscripten_stack_get_base"] = Module["asm"]["emscripten_stack_get_base"]).apply(null, arguments);
  8010. };
  8011. /** @type {function(...*):?} */
  8012. var _emscripten_stack_get_end = Module["_emscripten_stack_get_end"] = function() {
  8013. return (_emscripten_stack_get_end = Module["_emscripten_stack_get_end"] = Module["asm"]["emscripten_stack_get_end"]).apply(null, arguments);
  8014. };
  8015. /** @type {function(...*):?} */
  8016. var stackSave = Module["stackSave"] = createExportWrapper("stackSave");
  8017. /** @type {function(...*):?} */
  8018. var stackRestore = Module["stackRestore"] = createExportWrapper("stackRestore");
  8019. /** @type {function(...*):?} */
  8020. var stackAlloc = Module["stackAlloc"] = createExportWrapper("stackAlloc");
  8021. /** @type {function(...*):?} */
  8022. var _emscripten_stack_get_current = Module["_emscripten_stack_get_current"] = function() {
  8023. return (_emscripten_stack_get_current = Module["_emscripten_stack_get_current"] = Module["asm"]["emscripten_stack_get_current"]).apply(null, arguments);
  8024. };
  8025. /** @type {function(...*):?} */
  8026. var dynCall_iiiii = Module["dynCall_iiiii"] = createExportWrapper("dynCall_iiiii");
  8027. /** @type {function(...*):?} */
  8028. var dynCall_jiji = Module["dynCall_jiji"] = createExportWrapper("dynCall_jiji");
  8029. /** @type {function(...*):?} */
  8030. var dynCall_ji = Module["dynCall_ji"] = createExportWrapper("dynCall_ji");
  8031. /** @type {function(...*):?} */
  8032. var dynCall_viii = Module["dynCall_viii"] = createExportWrapper("dynCall_viii");
  8033. /** @type {function(...*):?} */
  8034. var dynCall_vi = Module["dynCall_vi"] = createExportWrapper("dynCall_vi");
  8035. /** @type {function(...*):?} */
  8036. var dynCall_v = Module["dynCall_v"] = createExportWrapper("dynCall_v");
  8037. /** @type {function(...*):?} */
  8038. var dynCall_ii = Module["dynCall_ii"] = createExportWrapper("dynCall_ii");
  8039. /** @type {function(...*):?} */
  8040. var dynCall_vii = Module["dynCall_vii"] = createExportWrapper("dynCall_vii");
  8041. /** @type {function(...*):?} */
  8042. var dynCall_viiii = Module["dynCall_viiii"] = createExportWrapper("dynCall_viiii");
  8043. /** @type {function(...*):?} */
  8044. var dynCall_iii = Module["dynCall_iii"] = createExportWrapper("dynCall_iii");
  8045. /** @type {function(...*):?} */
  8046. var dynCall_iiii = Module["dynCall_iiii"] = createExportWrapper("dynCall_iiii");
  8047. /** @type {function(...*):?} */
  8048. var dynCall_iiji = Module["dynCall_iiji"] = createExportWrapper("dynCall_iiji");
  8049. /** @type {function(...*):?} */
  8050. var dynCall_i = Module["dynCall_i"] = createExportWrapper("dynCall_i");
  8051. /** @type {function(...*):?} */
  8052. var dynCall_iid = Module["dynCall_iid"] = createExportWrapper("dynCall_iid");
  8053. /** @type {function(...*):?} */
  8054. var dynCall_iiiiii = Module["dynCall_iiiiii"] = createExportWrapper("dynCall_iiiiii");
  8055. /** @type {function(...*):?} */
  8056. var dynCall_iiiiiiiii = Module["dynCall_iiiiiiiii"] = createExportWrapper("dynCall_iiiiiiiii");
  8057. /** @type {function(...*):?} */
  8058. var dynCall_viiiii = Module["dynCall_viiiii"] = createExportWrapper("dynCall_viiiii");
  8059. /** @type {function(...*):?} */
  8060. var dynCall_iiiiiiii = Module["dynCall_iiiiiiii"] = createExportWrapper("dynCall_iiiiiiii");
  8061. /** @type {function(...*):?} */
  8062. var dynCall_iiiiiiiiii = Module["dynCall_iiiiiiiiii"] = createExportWrapper("dynCall_iiiiiiiiii");
  8063. /** @type {function(...*):?} */
  8064. var dynCall_iiiiiiiiiiiiiiff = Module["dynCall_iiiiiiiiiiiiiiff"] = createExportWrapper("dynCall_iiiiiiiiiiiiiiff");
  8065. /** @type {function(...*):?} */
  8066. var dynCall_viiiiiii = Module["dynCall_viiiiiii"] = createExportWrapper("dynCall_viiiiiii");
  8067. /** @type {function(...*):?} */
  8068. var dynCall_viiiiiiiiiii = Module["dynCall_viiiiiiiiiii"] = createExportWrapper("dynCall_viiiiiiiiiii");
  8069. /** @type {function(...*):?} */
  8070. var dynCall_iiiiiidiiff = Module["dynCall_iiiiiidiiff"] = createExportWrapper("dynCall_iiiiiidiiff");
  8071. /** @type {function(...*):?} */
  8072. var dynCall_vffff = Module["dynCall_vffff"] = createExportWrapper("dynCall_vffff");
  8073. /** @type {function(...*):?} */
  8074. var dynCall_vf = Module["dynCall_vf"] = createExportWrapper("dynCall_vf");
  8075. /** @type {function(...*):?} */
  8076. var dynCall_viiiiiiii = Module["dynCall_viiiiiiii"] = createExportWrapper("dynCall_viiiiiiii");
  8077. /** @type {function(...*):?} */
  8078. var dynCall_viiiiiiiii = Module["dynCall_viiiiiiiii"] = createExportWrapper("dynCall_viiiiiiiii");
  8079. /** @type {function(...*):?} */
  8080. var dynCall_vff = Module["dynCall_vff"] = createExportWrapper("dynCall_vff");
  8081. /** @type {function(...*):?} */
  8082. var dynCall_vfi = Module["dynCall_vfi"] = createExportWrapper("dynCall_vfi");
  8083. /** @type {function(...*):?} */
  8084. var dynCall_viif = Module["dynCall_viif"] = createExportWrapper("dynCall_viif");
  8085. /** @type {function(...*):?} */
  8086. var dynCall_vif = Module["dynCall_vif"] = createExportWrapper("dynCall_vif");
  8087. /** @type {function(...*):?} */
  8088. var dynCall_viff = Module["dynCall_viff"] = createExportWrapper("dynCall_viff");
  8089. /** @type {function(...*):?} */
  8090. var dynCall_vifff = Module["dynCall_vifff"] = createExportWrapper("dynCall_vifff");
  8091. /** @type {function(...*):?} */
  8092. var dynCall_viffff = Module["dynCall_viffff"] = createExportWrapper("dynCall_viffff");
  8093. /** @type {function(...*):?} */
  8094. var dynCall_viiiiii = Module["dynCall_viiiiii"] = createExportWrapper("dynCall_viiiiii");
  8095. /** @type {function(...*):?} */
  8096. var dynCall_iidiiii = Module["dynCall_iidiiii"] = createExportWrapper("dynCall_iidiiii");
  8097. /** @type {function(...*):?} */
  8098. var _asyncify_start_unwind = Module["_asyncify_start_unwind"] = createExportWrapper("asyncify_start_unwind");
  8099. /** @type {function(...*):?} */
  8100. var _asyncify_stop_unwind = Module["_asyncify_stop_unwind"] = createExportWrapper("asyncify_stop_unwind");
  8101. /** @type {function(...*):?} */
  8102. var _asyncify_start_rewind = Module["_asyncify_start_rewind"] = createExportWrapper("asyncify_start_rewind");
  8103. /** @type {function(...*):?} */
  8104. var _asyncify_stop_rewind = Module["_asyncify_stop_rewind"] = createExportWrapper("asyncify_stop_rewind");
  8105. var ___start_em_js = Module['___start_em_js'] = 6399572;
  8106. var ___stop_em_js = Module['___stop_em_js'] = 6400096;
  8107. // === Auto-generated postamble setup entry stuff ===
  8108. var unexportedRuntimeSymbols = [
  8109. 'run',
  8110. 'UTF8ArrayToString',
  8111. 'UTF8ToString',
  8112. 'stringToUTF8Array',
  8113. 'stringToUTF8',
  8114. 'lengthBytesUTF8',
  8115. 'addOnPreRun',
  8116. 'addOnInit',
  8117. 'addOnPreMain',
  8118. 'addOnExit',
  8119. 'addOnPostRun',
  8120. 'addRunDependency',
  8121. 'removeRunDependency',
  8122. 'FS_createFolder',
  8123. 'FS_createPath',
  8124. 'FS_createDataFile',
  8125. 'FS_createPreloadedFile',
  8126. 'FS_createLazyFile',
  8127. 'FS_createLink',
  8128. 'FS_createDevice',
  8129. 'FS_unlink',
  8130. 'getLEB',
  8131. 'getFunctionTables',
  8132. 'alignFunctionTables',
  8133. 'registerFunctions',
  8134. 'prettyPrint',
  8135. 'getCompilerSetting',
  8136. 'out',
  8137. 'err',
  8138. 'callMain',
  8139. 'abort',
  8140. 'keepRuntimeAlive',
  8141. 'wasmMemory',
  8142. 'stackAlloc',
  8143. 'stackSave',
  8144. 'stackRestore',
  8145. 'getTempRet0',
  8146. 'setTempRet0',
  8147. 'writeStackCookie',
  8148. 'checkStackCookie',
  8149. 'ptrToString',
  8150. 'zeroMemory',
  8151. 'stringToNewUTF8',
  8152. 'exitJS',
  8153. 'getHeapMax',
  8154. 'emscripten_realloc_buffer',
  8155. 'ENV',
  8156. 'ERRNO_CODES',
  8157. 'ERRNO_MESSAGES',
  8158. 'setErrNo',
  8159. 'inetPton4',
  8160. 'inetNtop4',
  8161. 'inetPton6',
  8162. 'inetNtop6',
  8163. 'readSockaddr',
  8164. 'writeSockaddr',
  8165. 'DNS',
  8166. 'getHostByName',
  8167. 'Protocols',
  8168. 'Sockets',
  8169. 'getRandomDevice',
  8170. 'warnOnce',
  8171. 'traverseStack',
  8172. 'UNWIND_CACHE',
  8173. 'convertPCtoSourceLocation',
  8174. 'readAsmConstArgsArray',
  8175. 'readAsmConstArgs',
  8176. 'mainThreadEM_ASM',
  8177. 'jstoi_q',
  8178. 'jstoi_s',
  8179. 'getExecutableName',
  8180. 'listenOnce',
  8181. 'autoResumeAudioContext',
  8182. 'dynCallLegacy',
  8183. 'getDynCaller',
  8184. 'dynCall',
  8185. 'handleException',
  8186. 'runtimeKeepalivePush',
  8187. 'runtimeKeepalivePop',
  8188. 'callUserCallback',
  8189. 'maybeExit',
  8190. 'safeSetTimeout',
  8191. 'asmjsMangle',
  8192. 'asyncLoad',
  8193. 'alignMemory',
  8194. 'mmapAlloc',
  8195. 'writeI53ToI64',
  8196. 'writeI53ToI64Clamped',
  8197. 'writeI53ToI64Signaling',
  8198. 'writeI53ToU64Clamped',
  8199. 'writeI53ToU64Signaling',
  8200. 'readI53FromI64',
  8201. 'readI53FromU64',
  8202. 'convertI32PairToI53',
  8203. 'convertI32PairToI53Checked',
  8204. 'convertU32PairToI53',
  8205. 'MAX_INT53',
  8206. 'MIN_INT53',
  8207. 'bigintToI53Checked',
  8208. 'getCFunc',
  8209. 'ccall',
  8210. 'cwrap',
  8211. 'uleb128Encode',
  8212. 'sigToWasmTypes',
  8213. 'generateFuncType',
  8214. 'convertJsFunctionToWasm',
  8215. 'freeTableIndexes',
  8216. 'functionsInTableMap',
  8217. 'getEmptyTableSlot',
  8218. 'updateTableMap',
  8219. 'addFunction',
  8220. 'removeFunction',
  8221. 'reallyNegative',
  8222. 'unSign',
  8223. 'strLen',
  8224. 'reSign',
  8225. 'formatString',
  8226. 'setValue',
  8227. 'getValue',
  8228. 'PATH',
  8229. 'PATH_FS',
  8230. 'intArrayFromString',
  8231. 'intArrayToString',
  8232. 'AsciiToString',
  8233. 'stringToAscii',
  8234. 'UTF16Decoder',
  8235. 'UTF16ToString',
  8236. 'stringToUTF16',
  8237. 'lengthBytesUTF16',
  8238. 'UTF32ToString',
  8239. 'stringToUTF32',
  8240. 'lengthBytesUTF32',
  8241. 'allocateUTF8',
  8242. 'allocateUTF8OnStack',
  8243. 'writeStringToMemory',
  8244. 'writeArrayToMemory',
  8245. 'writeAsciiToMemory',
  8246. 'SYSCALLS',
  8247. 'getSocketFromFD',
  8248. 'getSocketAddress',
  8249. 'JSEvents',
  8250. 'registerKeyEventCallback',
  8251. 'specialHTMLTargets',
  8252. 'maybeCStringToJsString',
  8253. 'findEventTarget',
  8254. 'findCanvasEventTarget',
  8255. 'getBoundingClientRect',
  8256. 'fillMouseEventData',
  8257. 'registerMouseEventCallback',
  8258. 'registerWheelEventCallback',
  8259. 'registerUiEventCallback',
  8260. 'registerFocusEventCallback',
  8261. 'fillDeviceOrientationEventData',
  8262. 'registerDeviceOrientationEventCallback',
  8263. 'fillDeviceMotionEventData',
  8264. 'registerDeviceMotionEventCallback',
  8265. 'screenOrientation',
  8266. 'fillOrientationChangeEventData',
  8267. 'registerOrientationChangeEventCallback',
  8268. 'fillFullscreenChangeEventData',
  8269. 'registerFullscreenChangeEventCallback',
  8270. 'JSEvents_requestFullscreen',
  8271. 'JSEvents_resizeCanvasForFullscreen',
  8272. 'registerRestoreOldStyle',
  8273. 'hideEverythingExceptGivenElement',
  8274. 'restoreHiddenElements',
  8275. 'setLetterbox',
  8276. 'currentFullscreenStrategy',
  8277. 'restoreOldWindowedStyle',
  8278. 'softFullscreenResizeWebGLRenderTarget',
  8279. 'doRequestFullscreen',
  8280. 'fillPointerlockChangeEventData',
  8281. 'registerPointerlockChangeEventCallback',
  8282. 'registerPointerlockErrorEventCallback',
  8283. 'requestPointerLock',
  8284. 'fillVisibilityChangeEventData',
  8285. 'registerVisibilityChangeEventCallback',
  8286. 'registerTouchEventCallback',
  8287. 'fillGamepadEventData',
  8288. 'registerGamepadEventCallback',
  8289. 'registerBeforeUnloadEventCallback',
  8290. 'fillBatteryEventData',
  8291. 'battery',
  8292. 'registerBatteryEventCallback',
  8293. 'setCanvasElementSize',
  8294. 'getCanvasElementSize',
  8295. 'demangle',
  8296. 'demangleAll',
  8297. 'jsStackTrace',
  8298. 'stackTrace',
  8299. 'ExitStatus',
  8300. 'getEnvStrings',
  8301. 'checkWasiClock',
  8302. 'doReadv',
  8303. 'doWritev',
  8304. 'dlopenMissingError',
  8305. 'createDyncallWrapper',
  8306. 'setImmediateWrapped',
  8307. 'clearImmediateWrapped',
  8308. 'polyfillSetImmediate',
  8309. 'uncaughtExceptionCount',
  8310. 'exceptionLast',
  8311. 'exceptionCaught',
  8312. 'ExceptionInfo',
  8313. 'exception_addRef',
  8314. 'exception_decRef',
  8315. 'Browser',
  8316. 'setMainLoop',
  8317. 'wget',
  8318. 'FS',
  8319. 'MEMFS',
  8320. 'TTY',
  8321. 'PIPEFS',
  8322. 'SOCKFS',
  8323. '_setNetworkCallback',
  8324. 'tempFixedLengthArray',
  8325. 'miniTempWebGLFloatBuffers',
  8326. 'heapObjectForWebGLType',
  8327. 'heapAccessShiftForWebGLHeap',
  8328. 'GL',
  8329. 'emscriptenWebGLGet',
  8330. 'computeUnpackAlignedImageSize',
  8331. 'emscriptenWebGLGetTexPixelData',
  8332. 'emscriptenWebGLGetUniform',
  8333. 'webglGetUniformLocation',
  8334. 'webglPrepareUniformLocationsBeforeFirstUse',
  8335. 'webglGetLeftBracePos',
  8336. 'emscriptenWebGLGetVertexAttrib',
  8337. 'writeGLArray',
  8338. 'AL',
  8339. 'SDL_unicode',
  8340. 'SDL_ttfContext',
  8341. 'SDL_audio',
  8342. 'SDL',
  8343. 'SDL_gfx',
  8344. 'GLUT',
  8345. 'EGL',
  8346. 'GLFW_Window',
  8347. 'GLFW',
  8348. 'GLEW',
  8349. 'IDBStore',
  8350. 'runAndAbortIfError',
  8351. 'Asyncify',
  8352. 'Fibers',
  8353. 'ALLOC_NORMAL',
  8354. 'ALLOC_STACK',
  8355. 'allocate',
  8356. ];
  8357. unexportedRuntimeSymbols.forEach(unexportedRuntimeSymbol);
  8358. var missingLibrarySymbols = [
  8359. 'inetPton4',
  8360. 'inetNtop4',
  8361. 'inetPton6',
  8362. 'inetNtop6',
  8363. 'readSockaddr',
  8364. 'writeSockaddr',
  8365. 'getHostByName',
  8366. 'traverseStack',
  8367. 'convertPCtoSourceLocation',
  8368. 'jstoi_s',
  8369. 'getDynCaller',
  8370. 'asmjsMangle',
  8371. 'writeI53ToI64Clamped',
  8372. 'writeI53ToI64Signaling',
  8373. 'writeI53ToU64Clamped',
  8374. 'writeI53ToU64Signaling',
  8375. 'convertI32PairToI53',
  8376. 'convertI32PairToI53Checked',
  8377. 'convertU32PairToI53',
  8378. 'getCFunc',
  8379. 'ccall',
  8380. 'cwrap',
  8381. 'uleb128Encode',
  8382. 'generateFuncType',
  8383. 'convertJsFunctionToWasm',
  8384. 'getEmptyTableSlot',
  8385. 'updateTableMap',
  8386. 'addFunction',
  8387. 'removeFunction',
  8388. 'reallyNegative',
  8389. 'unSign',
  8390. 'strLen',
  8391. 'reSign',
  8392. 'formatString',
  8393. 'intArrayToString',
  8394. 'AsciiToString',
  8395. 'stringToAscii',
  8396. 'UTF16ToString',
  8397. 'stringToUTF16',
  8398. 'lengthBytesUTF16',
  8399. 'UTF32ToString',
  8400. 'stringToUTF32',
  8401. 'lengthBytesUTF32',
  8402. 'writeStringToMemory',
  8403. 'writeArrayToMemory',
  8404. 'getSocketFromFD',
  8405. 'getSocketAddress',
  8406. 'fillDeviceOrientationEventData',
  8407. 'registerDeviceOrientationEventCallback',
  8408. 'fillDeviceMotionEventData',
  8409. 'registerDeviceMotionEventCallback',
  8410. 'screenOrientation',
  8411. 'fillOrientationChangeEventData',
  8412. 'registerOrientationChangeEventCallback',
  8413. 'hideEverythingExceptGivenElement',
  8414. 'restoreHiddenElements',
  8415. 'softFullscreenResizeWebGLRenderTarget',
  8416. 'registerPointerlockErrorEventCallback',
  8417. 'fillBatteryEventData',
  8418. 'battery',
  8419. 'registerBatteryEventCallback',
  8420. 'jsStackTrace',
  8421. 'stackTrace',
  8422. 'checkWasiClock',
  8423. 'createDyncallWrapper',
  8424. 'setImmediateWrapped',
  8425. 'clearImmediateWrapped',
  8426. 'polyfillSetImmediate',
  8427. 'ExceptionInfo',
  8428. 'exception_addRef',
  8429. 'exception_decRef',
  8430. '_setNetworkCallback',
  8431. 'writeGLArray',
  8432. 'SDL_unicode',
  8433. 'SDL_ttfContext',
  8434. 'SDL_audio',
  8435. 'GLFW_Window',
  8436. 'ALLOC_NORMAL',
  8437. 'ALLOC_STACK',
  8438. 'allocate',
  8439. ];
  8440. missingLibrarySymbols.forEach(missingLibrarySymbol)
  8441. var calledRun;
  8442. dependenciesFulfilled = function runCaller() {
  8443. // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
  8444. if (!calledRun) run();
  8445. if (!calledRun) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
  8446. };
  8447. function callMain(args) {
  8448. assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on Module["onRuntimeInitialized"])');
  8449. assert(__ATPRERUN__.length == 0, 'cannot call main when preRun functions remain to be called');
  8450. var entryFunction = Module['_main'];
  8451. args = args || [];
  8452. args.unshift(thisProgram);
  8453. var argc = args.length;
  8454. var argv = stackAlloc((argc + 1) * 4);
  8455. var argv_ptr = argv >> 2;
  8456. args.forEach((arg) => {
  8457. HEAP32[argv_ptr++] = allocateUTF8OnStack(arg);
  8458. });
  8459. HEAP32[argv_ptr] = 0;
  8460. try {
  8461. var ret = entryFunction(argc, argv);
  8462. // In PROXY_TO_PTHREAD builds, we should never exit the runtime below, as
  8463. // execution is asynchronously handed off to a pthread.
  8464. // if we're not running an evented main loop, it's time to exit
  8465. exitJS(ret, /* implicit = */ true);
  8466. return ret;
  8467. }
  8468. catch (e) {
  8469. return handleException(e);
  8470. }
  8471. }
  8472. function stackCheckInit() {
  8473. // This is normally called automatically during __wasm_call_ctors but need to
  8474. // get these values before even running any of the ctors so we call it redundantly
  8475. // here.
  8476. _emscripten_stack_init();
  8477. // TODO(sbc): Move writeStackCookie to native to to avoid this.
  8478. writeStackCookie();
  8479. }
  8480. /** @type {function(Array=)} */
  8481. function run(args) {
  8482. args = args || arguments_;
  8483. if (runDependencies > 0) {
  8484. return;
  8485. }
  8486. stackCheckInit();
  8487. preRun();
  8488. // a preRun added a dependency, run will be called later
  8489. if (runDependencies > 0) {
  8490. return;
  8491. }
  8492. function doRun() {
  8493. // run may have just been called through dependencies being fulfilled just in this very frame,
  8494. // or while the async setStatus time below was happening
  8495. if (calledRun) return;
  8496. calledRun = true;
  8497. Module['calledRun'] = true;
  8498. if (ABORT) return;
  8499. initRuntime();
  8500. preMain();
  8501. if (Module['onRuntimeInitialized']) Module['onRuntimeInitialized']();
  8502. if (shouldRunNow) callMain(args);
  8503. postRun();
  8504. }
  8505. if (Module['setStatus']) {
  8506. Module['setStatus']('Running...');
  8507. setTimeout(function() {
  8508. setTimeout(function() {
  8509. Module['setStatus']('');
  8510. }, 1);
  8511. doRun();
  8512. }, 1);
  8513. } else
  8514. {
  8515. doRun();
  8516. }
  8517. checkStackCookie();
  8518. }
  8519. if (Module['preInit']) {
  8520. if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];
  8521. while (Module['preInit'].length > 0) {
  8522. Module['preInit'].pop()();
  8523. }
  8524. }
  8525. // shouldRunNow refers to calling main(), not run().
  8526. var shouldRunNow = true;
  8527. if (Module['noInitialRun']) shouldRunNow = false;
  8528. run();