App.js 190 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660
  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. // --pre-jses are emitted after the Module integration code, so that they can
  16. // refer to Module (if they choose; they can also define Module)
  17. // {{PRE_JSES}}
  18. // Sometimes an existing Module object exists with properties
  19. // meant to overwrite the default module functionality. Here
  20. // we collect those properties and reapply _after_ we configure
  21. // the current environment's defaults to avoid having to be so
  22. // defensive during initialization.
  23. var moduleOverrides = {};
  24. var key;
  25. for (key in Module) {
  26. if (Module.hasOwnProperty(key)) {
  27. moduleOverrides[key] = Module[key];
  28. }
  29. }
  30. var arguments_ = [];
  31. var thisProgram = './this.program';
  32. var quit_ = function(status, toThrow) {
  33. throw toThrow;
  34. };
  35. // Determine the runtime environment we are in. You can customize this by
  36. // setting the ENVIRONMENT setting at compile time (see settings.js).
  37. var ENVIRONMENT_IS_WEB = false;
  38. var ENVIRONMENT_IS_WORKER = false;
  39. var ENVIRONMENT_IS_NODE = false;
  40. var ENVIRONMENT_IS_SHELL = false;
  41. ENVIRONMENT_IS_WEB = typeof window === 'object';
  42. ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';
  43. // N.b. Electron.js environment is simultaneously a NODE-environment, but
  44. // also a web environment.
  45. ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof process.versions === 'object' && typeof process.versions.node === 'string';
  46. ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
  47. // `/` should be present at the end if `scriptDirectory` is not empty
  48. var scriptDirectory = '';
  49. function locateFile(path) {
  50. if (Module['locateFile']) {
  51. return Module['locateFile'](path, scriptDirectory);
  52. }
  53. return scriptDirectory + path;
  54. }
  55. // Hooks that are implemented differently in different runtime environments.
  56. var read_,
  57. readAsync,
  58. readBinary,
  59. setWindowTitle;
  60. var nodeFS;
  61. var nodePath;
  62. if (ENVIRONMENT_IS_NODE) {
  63. if (ENVIRONMENT_IS_WORKER) {
  64. scriptDirectory = require('path').dirname(scriptDirectory) + '/';
  65. } else {
  66. scriptDirectory = __dirname + '/';
  67. }
  68. // include: node_shell_read.js
  69. read_ = function shell_read(filename, binary) {
  70. if (!nodeFS) nodeFS = require('fs');
  71. if (!nodePath) nodePath = require('path');
  72. filename = nodePath['normalize'](filename);
  73. return nodeFS['readFileSync'](filename, binary ? null : 'utf8');
  74. };
  75. readBinary = function readBinary(filename) {
  76. var ret = read_(filename, true);
  77. if (!ret.buffer) {
  78. ret = new Uint8Array(ret);
  79. }
  80. assert(ret.buffer);
  81. return ret;
  82. };
  83. // end include: node_shell_read.js
  84. if (process['argv'].length > 1) {
  85. thisProgram = process['argv'][1].replace(/\\/g, '/');
  86. }
  87. arguments_ = process['argv'].slice(2);
  88. if (typeof module !== 'undefined') {
  89. module['exports'] = Module;
  90. }
  91. process['on']('uncaughtException', function(ex) {
  92. // suppress ExitStatus exceptions from showing an error
  93. if (!(ex instanceof ExitStatus)) {
  94. throw ex;
  95. }
  96. });
  97. process['on']('unhandledRejection', abort);
  98. quit_ = function(status) {
  99. process['exit'](status);
  100. };
  101. Module['inspect'] = function () { return '[Emscripten Module object]'; };
  102. } else
  103. if (ENVIRONMENT_IS_SHELL) {
  104. if (typeof read != 'undefined') {
  105. read_ = function shell_read(f) {
  106. return read(f);
  107. };
  108. }
  109. readBinary = function readBinary(f) {
  110. var data;
  111. if (typeof readbuffer === 'function') {
  112. return new Uint8Array(readbuffer(f));
  113. }
  114. data = read(f, 'binary');
  115. assert(typeof data === 'object');
  116. return data;
  117. };
  118. if (typeof scriptArgs != 'undefined') {
  119. arguments_ = scriptArgs;
  120. } else if (typeof arguments != 'undefined') {
  121. arguments_ = arguments;
  122. }
  123. if (typeof quit === 'function') {
  124. quit_ = function(status) {
  125. quit(status);
  126. };
  127. }
  128. if (typeof print !== 'undefined') {
  129. // Prefer to use print/printErr where they exist, as they usually work better.
  130. if (typeof console === 'undefined') console = /** @type{!Console} */({});
  131. console.log = /** @type{!function(this:Console, ...*): undefined} */ (print);
  132. console.warn = console.error = /** @type{!function(this:Console, ...*): undefined} */ (typeof printErr !== 'undefined' ? printErr : print);
  133. }
  134. } else
  135. // Note that this includes Node.js workers when relevant (pthreads is enabled).
  136. // Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and
  137. // ENVIRONMENT_IS_NODE.
  138. if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
  139. if (ENVIRONMENT_IS_WORKER) { // Check worker, not web, since window could be polyfilled
  140. scriptDirectory = self.location.href;
  141. } else if (typeof document !== 'undefined' && document.currentScript) { // web
  142. scriptDirectory = document.currentScript.src;
  143. }
  144. // blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them.
  145. // otherwise, slice off the final part of the url to find the script directory.
  146. // if scriptDirectory does not contain a slash, lastIndexOf will return -1,
  147. // and scriptDirectory will correctly be replaced with an empty string.
  148. if (scriptDirectory.indexOf('blob:') !== 0) {
  149. scriptDirectory = scriptDirectory.substr(0, scriptDirectory.lastIndexOf('/')+1);
  150. } else {
  151. scriptDirectory = '';
  152. }
  153. // Differentiate the Web Worker from the Node Worker case, as reading must
  154. // be done differently.
  155. {
  156. // include: web_or_worker_shell_read.js
  157. read_ = function(url) {
  158. var xhr = new XMLHttpRequest();
  159. xhr.open('GET', url, false);
  160. xhr.send(null);
  161. return xhr.responseText;
  162. };
  163. if (ENVIRONMENT_IS_WORKER) {
  164. readBinary = function(url) {
  165. var xhr = new XMLHttpRequest();
  166. xhr.open('GET', url, false);
  167. xhr.responseType = 'arraybuffer';
  168. xhr.send(null);
  169. return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response));
  170. };
  171. }
  172. readAsync = function(url, onload, onerror) {
  173. var xhr = new XMLHttpRequest();
  174. xhr.open('GET', url, true);
  175. xhr.responseType = 'arraybuffer';
  176. xhr.onload = function() {
  177. if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
  178. onload(xhr.response);
  179. return;
  180. }
  181. onerror();
  182. };
  183. xhr.onerror = onerror;
  184. xhr.send(null);
  185. };
  186. // end include: web_or_worker_shell_read.js
  187. }
  188. setWindowTitle = function(title) { document.title = title };
  189. } else
  190. {
  191. }
  192. // Set up the out() and err() hooks, which are how we can print to stdout or
  193. // stderr, respectively.
  194. var out = Module['print'] || console.log.bind(console);
  195. var err = Module['printErr'] || console.warn.bind(console);
  196. // Merge back in the overrides
  197. for (key in moduleOverrides) {
  198. if (moduleOverrides.hasOwnProperty(key)) {
  199. Module[key] = moduleOverrides[key];
  200. }
  201. }
  202. // Free the object hierarchy contained in the overrides, this lets the GC
  203. // reclaim data used e.g. in memoryInitializerRequest, which is a large typed array.
  204. moduleOverrides = null;
  205. // Emit code to handle expected values on the Module object. This applies Module.x
  206. // to the proper local x. This has two benefits: first, we only emit it if it is
  207. // expected to arrive, and second, by using a local everywhere else that can be
  208. // minified.
  209. if (Module['arguments']) arguments_ = Module['arguments'];
  210. if (Module['thisProgram']) thisProgram = Module['thisProgram'];
  211. if (Module['quit']) quit_ = Module['quit'];
  212. // perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message
  213. var STACK_ALIGN = 16;
  214. function alignMemory(size, factor) {
  215. if (!factor) factor = STACK_ALIGN; // stack alignment (16-byte) by default
  216. return Math.ceil(size / factor) * factor;
  217. }
  218. function getNativeTypeSize(type) {
  219. switch (type) {
  220. case 'i1': case 'i8': return 1;
  221. case 'i16': return 2;
  222. case 'i32': return 4;
  223. case 'i64': return 8;
  224. case 'float': return 4;
  225. case 'double': return 8;
  226. default: {
  227. if (type[type.length-1] === '*') {
  228. return 4; // A pointer
  229. } else if (type[0] === 'i') {
  230. var bits = Number(type.substr(1));
  231. assert(bits % 8 === 0, 'getNativeTypeSize invalid bits ' + bits + ', type ' + type);
  232. return bits / 8;
  233. } else {
  234. return 0;
  235. }
  236. }
  237. }
  238. }
  239. function warnOnce(text) {
  240. if (!warnOnce.shown) warnOnce.shown = {};
  241. if (!warnOnce.shown[text]) {
  242. warnOnce.shown[text] = 1;
  243. err(text);
  244. }
  245. }
  246. // include: runtime_functions.js
  247. // Wraps a JS function as a wasm function with a given signature.
  248. function convertJsFunctionToWasm(func, sig) {
  249. // If the type reflection proposal is available, use the new
  250. // "WebAssembly.Function" constructor.
  251. // Otherwise, construct a minimal wasm module importing the JS function and
  252. // re-exporting it.
  253. if (typeof WebAssembly.Function === "function") {
  254. var typeNames = {
  255. 'i': 'i32',
  256. 'j': 'i64',
  257. 'f': 'f32',
  258. 'd': 'f64'
  259. };
  260. var type = {
  261. parameters: [],
  262. results: sig[0] == 'v' ? [] : [typeNames[sig[0]]]
  263. };
  264. for (var i = 1; i < sig.length; ++i) {
  265. type.parameters.push(typeNames[sig[i]]);
  266. }
  267. return new WebAssembly.Function(type, func);
  268. }
  269. // The module is static, with the exception of the type section, which is
  270. // generated based on the signature passed in.
  271. var typeSection = [
  272. 0x01, // id: section,
  273. 0x00, // length: 0 (placeholder)
  274. 0x01, // count: 1
  275. 0x60, // form: func
  276. ];
  277. var sigRet = sig.slice(0, 1);
  278. var sigParam = sig.slice(1);
  279. var typeCodes = {
  280. 'i': 0x7f, // i32
  281. 'j': 0x7e, // i64
  282. 'f': 0x7d, // f32
  283. 'd': 0x7c, // f64
  284. };
  285. // Parameters, length + signatures
  286. typeSection.push(sigParam.length);
  287. for (var i = 0; i < sigParam.length; ++i) {
  288. typeSection.push(typeCodes[sigParam[i]]);
  289. }
  290. // Return values, length + signatures
  291. // With no multi-return in MVP, either 0 (void) or 1 (anything else)
  292. if (sigRet == 'v') {
  293. typeSection.push(0x00);
  294. } else {
  295. typeSection = typeSection.concat([0x01, typeCodes[sigRet]]);
  296. }
  297. // Write the overall length of the type section back into the section header
  298. // (excepting the 2 bytes for the section id and length)
  299. typeSection[1] = typeSection.length - 2;
  300. // Rest of the module is static
  301. var bytes = new Uint8Array([
  302. 0x00, 0x61, 0x73, 0x6d, // magic ("\0asm")
  303. 0x01, 0x00, 0x00, 0x00, // version: 1
  304. ].concat(typeSection, [
  305. 0x02, 0x07, // import section
  306. // (import "e" "f" (func 0 (type 0)))
  307. 0x01, 0x01, 0x65, 0x01, 0x66, 0x00, 0x00,
  308. 0x07, 0x05, // export section
  309. // (export "f" (func 0 (type 0)))
  310. 0x01, 0x01, 0x66, 0x00, 0x00,
  311. ]));
  312. // We can compile this wasm module synchronously because it is very small.
  313. // This accepts an import (at "e.f"), that it reroutes to an export (at "f")
  314. var module = new WebAssembly.Module(bytes);
  315. var instance = new WebAssembly.Instance(module, {
  316. 'e': {
  317. 'f': func
  318. }
  319. });
  320. var wrappedFunc = instance.exports['f'];
  321. return wrappedFunc;
  322. }
  323. var freeTableIndexes = [];
  324. // Weak map of functions in the table to their indexes, created on first use.
  325. var functionsInTableMap;
  326. function getEmptyTableSlot() {
  327. // Reuse a free index if there is one, otherwise grow.
  328. if (freeTableIndexes.length) {
  329. return freeTableIndexes.pop();
  330. }
  331. // Grow the table
  332. try {
  333. wasmTable.grow(1);
  334. } catch (err) {
  335. if (!(err instanceof RangeError)) {
  336. throw err;
  337. }
  338. throw 'Unable to grow wasm table. Set ALLOW_TABLE_GROWTH.';
  339. }
  340. return wasmTable.length - 1;
  341. }
  342. // Add a wasm function to the table.
  343. function addFunctionWasm(func, sig) {
  344. // Check if the function is already in the table, to ensure each function
  345. // gets a unique index. First, create the map if this is the first use.
  346. if (!functionsInTableMap) {
  347. functionsInTableMap = new WeakMap();
  348. for (var i = 0; i < wasmTable.length; i++) {
  349. var item = wasmTable.get(i);
  350. // Ignore null values.
  351. if (item) {
  352. functionsInTableMap.set(item, i);
  353. }
  354. }
  355. }
  356. if (functionsInTableMap.has(func)) {
  357. return functionsInTableMap.get(func);
  358. }
  359. // It's not in the table, add it now.
  360. var ret = getEmptyTableSlot();
  361. // Set the new value.
  362. try {
  363. // Attempting to call this with JS function will cause of table.set() to fail
  364. wasmTable.set(ret, func);
  365. } catch (err) {
  366. if (!(err instanceof TypeError)) {
  367. throw err;
  368. }
  369. var wrapped = convertJsFunctionToWasm(func, sig);
  370. wasmTable.set(ret, wrapped);
  371. }
  372. functionsInTableMap.set(func, ret);
  373. return ret;
  374. }
  375. function removeFunction(index) {
  376. functionsInTableMap.delete(wasmTable.get(index));
  377. freeTableIndexes.push(index);
  378. }
  379. // 'sig' parameter is required for the llvm backend but only when func is not
  380. // already a WebAssembly function.
  381. function addFunction(func, sig) {
  382. return addFunctionWasm(func, sig);
  383. }
  384. // end include: runtime_functions.js
  385. // include: runtime_debug.js
  386. // end include: runtime_debug.js
  387. function makeBigInt(low, high, unsigned) {
  388. return unsigned ? ((+((low>>>0)))+((+((high>>>0)))*4294967296.0)) : ((+((low>>>0)))+((+((high|0)))*4294967296.0));
  389. }
  390. var tempRet0 = 0;
  391. var setTempRet0 = function(value) {
  392. tempRet0 = value;
  393. };
  394. var getTempRet0 = function() {
  395. return tempRet0;
  396. };
  397. // === Preamble library stuff ===
  398. // Documentation for the public APIs defined in this file must be updated in:
  399. // site/source/docs/api_reference/preamble.js.rst
  400. // A prebuilt local version of the documentation is available at:
  401. // site/build/text/docs/api_reference/preamble.js.txt
  402. // You can also build docs locally as HTML or other formats in site/
  403. // An online HTML version (which may be of a different version of Emscripten)
  404. // is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html
  405. var wasmBinary;if (Module['wasmBinary']) wasmBinary = Module['wasmBinary'];
  406. var noExitRuntime;if (Module['noExitRuntime']) noExitRuntime = Module['noExitRuntime'];
  407. if (typeof WebAssembly !== 'object') {
  408. abort('no native wasm support detected');
  409. }
  410. // include: runtime_safe_heap.js
  411. // In MINIMAL_RUNTIME, setValue() and getValue() are only available when building with safe heap enabled, for heap safety checking.
  412. // In traditional runtime, setValue() and getValue() are always available (although their use is highly discouraged due to perf penalties)
  413. /** @param {number} ptr
  414. @param {number} value
  415. @param {string} type
  416. @param {number|boolean=} noSafe */
  417. function setValue(ptr, value, type, noSafe) {
  418. type = type || 'i8';
  419. if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
  420. switch(type) {
  421. case 'i1': HEAP8[((ptr)>>0)] = value; break;
  422. case 'i8': HEAP8[((ptr)>>0)] = value; break;
  423. case 'i16': HEAP16[((ptr)>>1)] = value; break;
  424. case 'i32': HEAP32[((ptr)>>2)] = value; break;
  425. 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;
  426. case 'float': HEAPF32[((ptr)>>2)] = value; break;
  427. case 'double': HEAPF64[((ptr)>>3)] = value; break;
  428. default: abort('invalid type for setValue: ' + type);
  429. }
  430. }
  431. /** @param {number} ptr
  432. @param {string} type
  433. @param {number|boolean=} noSafe */
  434. function getValue(ptr, type, noSafe) {
  435. type = type || 'i8';
  436. if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
  437. switch(type) {
  438. case 'i1': return HEAP8[((ptr)>>0)];
  439. case 'i8': return HEAP8[((ptr)>>0)];
  440. case 'i16': return HEAP16[((ptr)>>1)];
  441. case 'i32': return HEAP32[((ptr)>>2)];
  442. case 'i64': return HEAP32[((ptr)>>2)];
  443. case 'float': return HEAPF32[((ptr)>>2)];
  444. case 'double': return HEAPF64[((ptr)>>3)];
  445. default: abort('invalid type for getValue: ' + type);
  446. }
  447. return null;
  448. }
  449. // end include: runtime_safe_heap.js
  450. // Wasm globals
  451. var wasmMemory;
  452. //========================================
  453. // Runtime essentials
  454. //========================================
  455. // whether we are quitting the application. no code should run after this.
  456. // set in exit() and abort()
  457. var ABORT = false;
  458. // set by exit() and abort(). Passed to 'onExit' handler.
  459. // NOTE: This is also used as the process return code code in shell environments
  460. // but only when noExitRuntime is false.
  461. var EXITSTATUS;
  462. /** @type {function(*, string=)} */
  463. function assert(condition, text) {
  464. if (!condition) {
  465. abort('Assertion failed: ' + text);
  466. }
  467. }
  468. // Returns the C function with a specified identifier (for C++, you need to do manual name mangling)
  469. function getCFunc(ident) {
  470. var func = Module['_' + ident]; // closure exported function
  471. assert(func, 'Cannot call unknown function ' + ident + ', make sure it is exported');
  472. return func;
  473. }
  474. // C calling interface.
  475. /** @param {string|null=} returnType
  476. @param {Array=} argTypes
  477. @param {Arguments|Array=} args
  478. @param {Object=} opts */
  479. function ccall(ident, returnType, argTypes, args, opts) {
  480. // For fast lookup of conversion functions
  481. var toC = {
  482. 'string': function(str) {
  483. var ret = 0;
  484. if (str !== null && str !== undefined && str !== 0) { // null string
  485. // at most 4 bytes per UTF-8 code point, +1 for the trailing '\0'
  486. var len = (str.length << 2) + 1;
  487. ret = stackAlloc(len);
  488. stringToUTF8(str, ret, len);
  489. }
  490. return ret;
  491. },
  492. 'array': function(arr) {
  493. var ret = stackAlloc(arr.length);
  494. writeArrayToMemory(arr, ret);
  495. return ret;
  496. }
  497. };
  498. function convertReturnValue(ret) {
  499. if (returnType === 'string') return UTF8ToString(ret);
  500. if (returnType === 'boolean') return Boolean(ret);
  501. return ret;
  502. }
  503. var func = getCFunc(ident);
  504. var cArgs = [];
  505. var stack = 0;
  506. if (args) {
  507. for (var i = 0; i < args.length; i++) {
  508. var converter = toC[argTypes[i]];
  509. if (converter) {
  510. if (stack === 0) stack = stackSave();
  511. cArgs[i] = converter(args[i]);
  512. } else {
  513. cArgs[i] = args[i];
  514. }
  515. }
  516. }
  517. var ret = func.apply(null, cArgs);
  518. var asyncMode = opts && opts.async;
  519. var runningAsync = typeof Asyncify === 'object' && Asyncify.currData;
  520. var prevRunningAsync = typeof Asyncify === 'object' && Asyncify.asyncFinalizers.length > 0;
  521. // Check if we started an async operation just now.
  522. if (runningAsync && !prevRunningAsync) {
  523. // If so, the WASM function ran asynchronous and unwound its stack.
  524. // We need to return a Promise that resolves the return value
  525. // once the stack is rewound and execution finishes.
  526. return new Promise(function(resolve) {
  527. Asyncify.asyncFinalizers.push(function(ret) {
  528. if (stack !== 0) stackRestore(stack);
  529. resolve(convertReturnValue(ret));
  530. });
  531. });
  532. }
  533. ret = convertReturnValue(ret);
  534. if (stack !== 0) stackRestore(stack);
  535. // If this is an async ccall, ensure we return a promise
  536. if (opts && opts.async) return Promise.resolve(ret);
  537. return ret;
  538. }
  539. /** @param {string=} returnType
  540. @param {Array=} argTypes
  541. @param {Object=} opts */
  542. function cwrap(ident, returnType, argTypes, opts) {
  543. argTypes = argTypes || [];
  544. // When the function takes numbers and returns a number, we can just return
  545. // the original function
  546. var numericArgs = argTypes.every(function(type){ return type === 'number'});
  547. var numericRet = returnType !== 'string';
  548. if (numericRet && numericArgs && !opts) {
  549. return getCFunc(ident);
  550. }
  551. return function() {
  552. return ccall(ident, returnType, argTypes, arguments, opts);
  553. }
  554. }
  555. var ALLOC_NORMAL = 0; // Tries to use _malloc()
  556. var ALLOC_STACK = 1; // Lives for the duration of the current function call
  557. // allocate(): This is for internal use. You can use it yourself as well, but the interface
  558. // is a little tricky (see docs right below). The reason is that it is optimized
  559. // for multiple syntaxes to save space in generated code. So you should
  560. // normally not use allocate(), and instead allocate memory using _malloc(),
  561. // initialize it with setValue(), and so forth.
  562. // @slab: An array of data.
  563. // @allocator: How to allocate memory, see ALLOC_*
  564. /** @type {function((Uint8Array|Array<number>), number)} */
  565. function allocate(slab, allocator) {
  566. var ret;
  567. if (allocator == ALLOC_STACK) {
  568. ret = stackAlloc(slab.length);
  569. } else {
  570. ret = _malloc(slab.length);
  571. }
  572. if (slab.subarray || slab.slice) {
  573. HEAPU8.set(/** @type {!Uint8Array} */(slab), ret);
  574. } else {
  575. HEAPU8.set(new Uint8Array(slab), ret);
  576. }
  577. return ret;
  578. }
  579. // include: runtime_strings.js
  580. // runtime_strings.js: Strings related runtime functions that are part of both MINIMAL_RUNTIME and regular runtime.
  581. // Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the given array that contains uint8 values, returns
  582. // a copy of that string as a Javascript String object.
  583. var UTF8Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf8') : undefined;
  584. /**
  585. * @param {number} idx
  586. * @param {number=} maxBytesToRead
  587. * @return {string}
  588. */
  589. function UTF8ArrayToString(heap, idx, maxBytesToRead) {
  590. var endIdx = idx + maxBytesToRead;
  591. var endPtr = idx;
  592. // TextDecoder needs to know the byte length in advance, it doesn't stop on null terminator by itself.
  593. // Also, use the length info to avoid running tiny strings through TextDecoder, since .subarray() allocates garbage.
  594. // (As a tiny code save trick, compare endPtr against endIdx using a negation, so that undefined means Infinity)
  595. while (heap[endPtr] && !(endPtr >= endIdx)) ++endPtr;
  596. if (endPtr - idx > 16 && heap.subarray && UTF8Decoder) {
  597. return UTF8Decoder.decode(heap.subarray(idx, endPtr));
  598. } else {
  599. var str = '';
  600. // If building with TextDecoder, we have already computed the string length above, so test loop end condition against that
  601. while (idx < endPtr) {
  602. // For UTF8 byte structure, see:
  603. // http://en.wikipedia.org/wiki/UTF-8#Description
  604. // https://www.ietf.org/rfc/rfc2279.txt
  605. // https://tools.ietf.org/html/rfc3629
  606. var u0 = heap[idx++];
  607. if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; }
  608. var u1 = heap[idx++] & 63;
  609. if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; }
  610. var u2 = heap[idx++] & 63;
  611. if ((u0 & 0xF0) == 0xE0) {
  612. u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
  613. } else {
  614. u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heap[idx++] & 63);
  615. }
  616. if (u0 < 0x10000) {
  617. str += String.fromCharCode(u0);
  618. } else {
  619. var ch = u0 - 0x10000;
  620. str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
  621. }
  622. }
  623. }
  624. return str;
  625. }
  626. // Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the emscripten HEAP, returns a
  627. // copy of that string as a Javascript String object.
  628. // maxBytesToRead: an optional length that specifies the maximum number of bytes to read. You can omit
  629. // this parameter to scan the string until the first \0 byte. If maxBytesToRead is
  630. // passed, and the string at [ptr, ptr+maxBytesToReadr[ contains a null byte in the
  631. // middle, then the string will cut short at that byte index (i.e. maxBytesToRead will
  632. // not produce a string of exact length [ptr, ptr+maxBytesToRead[)
  633. // N.B. mixing frequent uses of UTF8ToString() with and without maxBytesToRead may
  634. // throw JS JIT optimizations off, so it is worth to consider consistently using one
  635. // style or the other.
  636. /**
  637. * @param {number} ptr
  638. * @param {number=} maxBytesToRead
  639. * @return {string}
  640. */
  641. function UTF8ToString(ptr, maxBytesToRead) {
  642. return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : '';
  643. }
  644. // Copies the given Javascript String object 'str' to the given byte array at address 'outIdx',
  645. // encoded in UTF8 form and null-terminated. The copy will require at most str.length*4+1 bytes of space in the HEAP.
  646. // Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write.
  647. // Parameters:
  648. // str: the Javascript string to copy.
  649. // heap: the array to copy to. Each index in this array is assumed to be one 8-byte element.
  650. // outIdx: The starting offset in the array to begin the copying.
  651. // maxBytesToWrite: The maximum number of bytes this function can write to the array.
  652. // This count should include the null terminator,
  653. // i.e. if maxBytesToWrite=1, only the null terminator will be written and nothing else.
  654. // maxBytesToWrite=0 does not write any bytes to the output, not even the null terminator.
  655. // Returns the number of bytes written, EXCLUDING the null terminator.
  656. function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) {
  657. if (!(maxBytesToWrite > 0)) // Parameter maxBytesToWrite is not optional. Negative values, 0, null, undefined and false each don't write out any bytes.
  658. return 0;
  659. var startIdx = outIdx;
  660. var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator.
  661. for (var i = 0; i < str.length; ++i) {
  662. // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8.
  663. // See http://unicode.org/faq/utf_bom.html#utf16-3
  664. // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description and https://www.ietf.org/rfc/rfc2279.txt and https://tools.ietf.org/html/rfc3629
  665. var u = str.charCodeAt(i); // possibly a lead surrogate
  666. if (u >= 0xD800 && u <= 0xDFFF) {
  667. var u1 = str.charCodeAt(++i);
  668. u = 0x10000 + ((u & 0x3FF) << 10) | (u1 & 0x3FF);
  669. }
  670. if (u <= 0x7F) {
  671. if (outIdx >= endIdx) break;
  672. heap[outIdx++] = u;
  673. } else if (u <= 0x7FF) {
  674. if (outIdx + 1 >= endIdx) break;
  675. heap[outIdx++] = 0xC0 | (u >> 6);
  676. heap[outIdx++] = 0x80 | (u & 63);
  677. } else if (u <= 0xFFFF) {
  678. if (outIdx + 2 >= endIdx) break;
  679. heap[outIdx++] = 0xE0 | (u >> 12);
  680. heap[outIdx++] = 0x80 | ((u >> 6) & 63);
  681. heap[outIdx++] = 0x80 | (u & 63);
  682. } else {
  683. if (outIdx + 3 >= endIdx) break;
  684. heap[outIdx++] = 0xF0 | (u >> 18);
  685. heap[outIdx++] = 0x80 | ((u >> 12) & 63);
  686. heap[outIdx++] = 0x80 | ((u >> 6) & 63);
  687. heap[outIdx++] = 0x80 | (u & 63);
  688. }
  689. }
  690. // Null-terminate the pointer to the buffer.
  691. heap[outIdx] = 0;
  692. return outIdx - startIdx;
  693. }
  694. // Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
  695. // null-terminated and encoded in UTF8 form. The copy will require at most str.length*4+1 bytes of space in the HEAP.
  696. // Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write.
  697. // Returns the number of bytes written, EXCLUDING the null terminator.
  698. function stringToUTF8(str, outPtr, maxBytesToWrite) {
  699. return stringToUTF8Array(str, HEAPU8,outPtr, maxBytesToWrite);
  700. }
  701. // Returns the number of bytes the given Javascript string takes if encoded as a UTF8 byte array, EXCLUDING the null terminator byte.
  702. function lengthBytesUTF8(str) {
  703. var len = 0;
  704. for (var i = 0; i < str.length; ++i) {
  705. // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8.
  706. // See http://unicode.org/faq/utf_bom.html#utf16-3
  707. var u = str.charCodeAt(i); // possibly a lead surrogate
  708. if (u >= 0xD800 && u <= 0xDFFF) u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF);
  709. if (u <= 0x7F) ++len;
  710. else if (u <= 0x7FF) len += 2;
  711. else if (u <= 0xFFFF) len += 3;
  712. else len += 4;
  713. }
  714. return len;
  715. }
  716. // end include: runtime_strings.js
  717. // include: runtime_strings_extra.js
  718. // runtime_strings_extra.js: Strings related runtime functions that are available only in regular runtime.
  719. // Given a pointer 'ptr' to a null-terminated ASCII-encoded string in the emscripten HEAP, returns
  720. // a copy of that string as a Javascript String object.
  721. function AsciiToString(ptr) {
  722. var str = '';
  723. while (1) {
  724. var ch = HEAPU8[((ptr++)>>0)];
  725. if (!ch) return str;
  726. str += String.fromCharCode(ch);
  727. }
  728. }
  729. // Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
  730. // null-terminated and encoded in ASCII form. The copy will require at most str.length+1 bytes of space in the HEAP.
  731. function stringToAscii(str, outPtr) {
  732. return writeAsciiToMemory(str, outPtr, false);
  733. }
  734. // Given a pointer 'ptr' to a null-terminated UTF16LE-encoded string in the emscripten HEAP, returns
  735. // a copy of that string as a Javascript String object.
  736. var UTF16Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-16le') : undefined;
  737. function UTF16ToString(ptr, maxBytesToRead) {
  738. var endPtr = ptr;
  739. // TextDecoder needs to know the byte length in advance, it doesn't stop on null terminator by itself.
  740. // Also, use the length info to avoid running tiny strings through TextDecoder, since .subarray() allocates garbage.
  741. var idx = endPtr >> 1;
  742. var maxIdx = idx + maxBytesToRead / 2;
  743. // If maxBytesToRead is not passed explicitly, it will be undefined, and this
  744. // will always evaluate to true. This saves on code size.
  745. while (!(idx >= maxIdx) && HEAPU16[idx]) ++idx;
  746. endPtr = idx << 1;
  747. if (endPtr - ptr > 32 && UTF16Decoder) {
  748. return UTF16Decoder.decode(HEAPU8.subarray(ptr, endPtr));
  749. } else {
  750. var str = '';
  751. // If maxBytesToRead is not passed explicitly, it will be undefined, and the for-loop's condition
  752. // will always evaluate to true. The loop is then terminated on the first null char.
  753. for (var i = 0; !(i >= maxBytesToRead / 2); ++i) {
  754. var codeUnit = HEAP16[(((ptr)+(i*2))>>1)];
  755. if (codeUnit == 0) break;
  756. // fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through.
  757. str += String.fromCharCode(codeUnit);
  758. }
  759. return str;
  760. }
  761. }
  762. // Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
  763. // null-terminated and encoded in UTF16 form. The copy will require at most str.length*4+2 bytes of space in the HEAP.
  764. // Use the function lengthBytesUTF16() to compute the exact number of bytes (excluding null terminator) that this function will write.
  765. // Parameters:
  766. // str: the Javascript string to copy.
  767. // outPtr: Byte address in Emscripten HEAP where to write the string to.
  768. // maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null
  769. // terminator, i.e. if maxBytesToWrite=2, only the null terminator will be written and nothing else.
  770. // maxBytesToWrite<2 does not write any bytes to the output, not even the null terminator.
  771. // Returns the number of bytes written, EXCLUDING the null terminator.
  772. function stringToUTF16(str, outPtr, maxBytesToWrite) {
  773. // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed.
  774. if (maxBytesToWrite === undefined) {
  775. maxBytesToWrite = 0x7FFFFFFF;
  776. }
  777. if (maxBytesToWrite < 2) return 0;
  778. maxBytesToWrite -= 2; // Null terminator.
  779. var startPtr = outPtr;
  780. var numCharsToWrite = (maxBytesToWrite < str.length*2) ? (maxBytesToWrite / 2) : str.length;
  781. for (var i = 0; i < numCharsToWrite; ++i) {
  782. // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP.
  783. var codeUnit = str.charCodeAt(i); // possibly a lead surrogate
  784. HEAP16[((outPtr)>>1)] = codeUnit;
  785. outPtr += 2;
  786. }
  787. // Null-terminate the pointer to the HEAP.
  788. HEAP16[((outPtr)>>1)] = 0;
  789. return outPtr - startPtr;
  790. }
  791. // Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte.
  792. function lengthBytesUTF16(str) {
  793. return str.length*2;
  794. }
  795. function UTF32ToString(ptr, maxBytesToRead) {
  796. var i = 0;
  797. var str = '';
  798. // If maxBytesToRead is not passed explicitly, it will be undefined, and this
  799. // will always evaluate to true. This saves on code size.
  800. while (!(i >= maxBytesToRead / 4)) {
  801. var utf32 = HEAP32[(((ptr)+(i*4))>>2)];
  802. if (utf32 == 0) break;
  803. ++i;
  804. // Gotcha: fromCharCode constructs a character from a UTF-16 encoded code (pair), not from a Unicode code point! So encode the code point to UTF-16 for constructing.
  805. // See http://unicode.org/faq/utf_bom.html#utf16-3
  806. if (utf32 >= 0x10000) {
  807. var ch = utf32 - 0x10000;
  808. str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
  809. } else {
  810. str += String.fromCharCode(utf32);
  811. }
  812. }
  813. return str;
  814. }
  815. // Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
  816. // null-terminated and encoded in UTF32 form. The copy will require at most str.length*4+4 bytes of space in the HEAP.
  817. // Use the function lengthBytesUTF32() to compute the exact number of bytes (excluding null terminator) that this function will write.
  818. // Parameters:
  819. // str: the Javascript string to copy.
  820. // outPtr: Byte address in Emscripten HEAP where to write the string to.
  821. // maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null
  822. // terminator, i.e. if maxBytesToWrite=4, only the null terminator will be written and nothing else.
  823. // maxBytesToWrite<4 does not write any bytes to the output, not even the null terminator.
  824. // Returns the number of bytes written, EXCLUDING the null terminator.
  825. function stringToUTF32(str, outPtr, maxBytesToWrite) {
  826. // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed.
  827. if (maxBytesToWrite === undefined) {
  828. maxBytesToWrite = 0x7FFFFFFF;
  829. }
  830. if (maxBytesToWrite < 4) return 0;
  831. var startPtr = outPtr;
  832. var endPtr = startPtr + maxBytesToWrite - 4;
  833. for (var i = 0; i < str.length; ++i) {
  834. // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap.
  835. // See http://unicode.org/faq/utf_bom.html#utf16-3
  836. var codeUnit = str.charCodeAt(i); // possibly a lead surrogate
  837. if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) {
  838. var trailSurrogate = str.charCodeAt(++i);
  839. codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF);
  840. }
  841. HEAP32[((outPtr)>>2)] = codeUnit;
  842. outPtr += 4;
  843. if (outPtr + 4 > endPtr) break;
  844. }
  845. // Null-terminate the pointer to the HEAP.
  846. HEAP32[((outPtr)>>2)] = 0;
  847. return outPtr - startPtr;
  848. }
  849. // Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte.
  850. function lengthBytesUTF32(str) {
  851. var len = 0;
  852. for (var i = 0; i < str.length; ++i) {
  853. // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap.
  854. // See http://unicode.org/faq/utf_bom.html#utf16-3
  855. var codeUnit = str.charCodeAt(i);
  856. if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) ++i; // possibly a lead surrogate, so skip over the tail surrogate.
  857. len += 4;
  858. }
  859. return len;
  860. }
  861. // Allocate heap space for a JS string, and write it there.
  862. // It is the responsibility of the caller to free() that memory.
  863. function allocateUTF8(str) {
  864. var size = lengthBytesUTF8(str) + 1;
  865. var ret = _malloc(size);
  866. if (ret) stringToUTF8Array(str, HEAP8, ret, size);
  867. return ret;
  868. }
  869. // Allocate stack space for a JS string, and write it there.
  870. function allocateUTF8OnStack(str) {
  871. var size = lengthBytesUTF8(str) + 1;
  872. var ret = stackAlloc(size);
  873. stringToUTF8Array(str, HEAP8, ret, size);
  874. return ret;
  875. }
  876. // Deprecated: This function should not be called because it is unsafe and does not provide
  877. // a maximum length limit of how many bytes it is allowed to write. Prefer calling the
  878. // function stringToUTF8Array() instead, which takes in a maximum length that can be used
  879. // to be secure from out of bounds writes.
  880. /** @deprecated
  881. @param {boolean=} dontAddNull */
  882. function writeStringToMemory(string, buffer, dontAddNull) {
  883. warnOnce('writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!');
  884. var /** @type {number} */ lastChar, /** @type {number} */ end;
  885. if (dontAddNull) {
  886. // stringToUTF8Array always appends null. If we don't want to do that, remember the
  887. // character that existed at the location where the null will be placed, and restore
  888. // that after the write (below).
  889. end = buffer + lengthBytesUTF8(string);
  890. lastChar = HEAP8[end];
  891. }
  892. stringToUTF8(string, buffer, Infinity);
  893. if (dontAddNull) HEAP8[end] = lastChar; // Restore the value under the null character.
  894. }
  895. function writeArrayToMemory(array, buffer) {
  896. HEAP8.set(array, buffer);
  897. }
  898. /** @param {boolean=} dontAddNull */
  899. function writeAsciiToMemory(str, buffer, dontAddNull) {
  900. for (var i = 0; i < str.length; ++i) {
  901. HEAP8[((buffer++)>>0)] = str.charCodeAt(i);
  902. }
  903. // Null-terminate the pointer to the HEAP.
  904. if (!dontAddNull) HEAP8[((buffer)>>0)] = 0;
  905. }
  906. // end include: runtime_strings_extra.js
  907. // Memory management
  908. function alignUp(x, multiple) {
  909. if (x % multiple > 0) {
  910. x += multiple - (x % multiple);
  911. }
  912. return x;
  913. }
  914. var HEAP,
  915. /** @type {ArrayBuffer} */
  916. buffer,
  917. /** @type {Int8Array} */
  918. HEAP8,
  919. /** @type {Uint8Array} */
  920. HEAPU8,
  921. /** @type {Int16Array} */
  922. HEAP16,
  923. /** @type {Uint16Array} */
  924. HEAPU16,
  925. /** @type {Int32Array} */
  926. HEAP32,
  927. /** @type {Uint32Array} */
  928. HEAPU32,
  929. /** @type {Float32Array} */
  930. HEAPF32,
  931. /** @type {Float64Array} */
  932. HEAPF64;
  933. function updateGlobalBufferAndViews(buf) {
  934. buffer = buf;
  935. Module['HEAP8'] = HEAP8 = new Int8Array(buf);
  936. Module['HEAP16'] = HEAP16 = new Int16Array(buf);
  937. Module['HEAP32'] = HEAP32 = new Int32Array(buf);
  938. Module['HEAPU8'] = HEAPU8 = new Uint8Array(buf);
  939. Module['HEAPU16'] = HEAPU16 = new Uint16Array(buf);
  940. Module['HEAPU32'] = HEAPU32 = new Uint32Array(buf);
  941. Module['HEAPF32'] = HEAPF32 = new Float32Array(buf);
  942. Module['HEAPF64'] = HEAPF64 = new Float64Array(buf);
  943. }
  944. var TOTAL_STACK = 5242880;
  945. var INITIAL_MEMORY = Module['INITIAL_MEMORY'] || 16777216;
  946. // include: runtime_init_table.js
  947. // In regular non-RELOCATABLE mode the table is exported
  948. // from the wasm module and this will be assigned once
  949. // the exports are available.
  950. var wasmTable;
  951. // end include: runtime_init_table.js
  952. // include: runtime_stack_check.js
  953. // end include: runtime_stack_check.js
  954. // include: runtime_assertions.js
  955. // end include: runtime_assertions.js
  956. var __ATPRERUN__ = []; // functions called before the runtime is initialized
  957. var __ATINIT__ = []; // functions called during startup
  958. var __ATMAIN__ = []; // functions called when main() is to be run
  959. var __ATEXIT__ = []; // functions called during shutdown
  960. var __ATPOSTRUN__ = []; // functions called after the main() is called
  961. var runtimeInitialized = false;
  962. var runtimeExited = false;
  963. __ATINIT__.push({ func: function() { ___wasm_call_ctors() } });
  964. function preRun() {
  965. if (Module['preRun']) {
  966. if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];
  967. while (Module['preRun'].length) {
  968. addOnPreRun(Module['preRun'].shift());
  969. }
  970. }
  971. callRuntimeCallbacks(__ATPRERUN__);
  972. }
  973. function initRuntime() {
  974. runtimeInitialized = true;
  975. callRuntimeCallbacks(__ATINIT__);
  976. }
  977. function preMain() {
  978. callRuntimeCallbacks(__ATMAIN__);
  979. }
  980. function exitRuntime() {
  981. runtimeExited = true;
  982. }
  983. function postRun() {
  984. if (Module['postRun']) {
  985. if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];
  986. while (Module['postRun'].length) {
  987. addOnPostRun(Module['postRun'].shift());
  988. }
  989. }
  990. callRuntimeCallbacks(__ATPOSTRUN__);
  991. }
  992. function addOnPreRun(cb) {
  993. __ATPRERUN__.unshift(cb);
  994. }
  995. function addOnInit(cb) {
  996. __ATINIT__.unshift(cb);
  997. }
  998. function addOnPreMain(cb) {
  999. __ATMAIN__.unshift(cb);
  1000. }
  1001. function addOnExit(cb) {
  1002. }
  1003. function addOnPostRun(cb) {
  1004. __ATPOSTRUN__.unshift(cb);
  1005. }
  1006. // include: runtime_math.js
  1007. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul
  1008. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround
  1009. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32
  1010. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc
  1011. // end include: runtime_math.js
  1012. // A counter of dependencies for calling run(). If we need to
  1013. // do asynchronous work before running, increment this and
  1014. // decrement it. Incrementing must happen in a place like
  1015. // Module.preRun (used by emcc to add file preloading).
  1016. // Note that you can add dependencies in preRun, even though
  1017. // it happens right before run - run will be postponed until
  1018. // the dependencies are met.
  1019. var runDependencies = 0;
  1020. var runDependencyWatcher = null;
  1021. var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled
  1022. function getUniqueRunDependency(id) {
  1023. return id;
  1024. }
  1025. function addRunDependency(id) {
  1026. runDependencies++;
  1027. if (Module['monitorRunDependencies']) {
  1028. Module['monitorRunDependencies'](runDependencies);
  1029. }
  1030. }
  1031. function removeRunDependency(id) {
  1032. runDependencies--;
  1033. if (Module['monitorRunDependencies']) {
  1034. Module['monitorRunDependencies'](runDependencies);
  1035. }
  1036. if (runDependencies == 0) {
  1037. if (runDependencyWatcher !== null) {
  1038. clearInterval(runDependencyWatcher);
  1039. runDependencyWatcher = null;
  1040. }
  1041. if (dependenciesFulfilled) {
  1042. var callback = dependenciesFulfilled;
  1043. dependenciesFulfilled = null;
  1044. callback(); // can add another dependenciesFulfilled
  1045. }
  1046. }
  1047. }
  1048. Module["preloadedImages"] = {}; // maps url to image data
  1049. Module["preloadedAudios"] = {}; // maps url to audio data
  1050. /** @param {string|number=} what */
  1051. function abort(what) {
  1052. if (Module['onAbort']) {
  1053. Module['onAbort'](what);
  1054. }
  1055. what += '';
  1056. err(what);
  1057. ABORT = true;
  1058. EXITSTATUS = 1;
  1059. what = 'abort(' + what + '). Build with -s ASSERTIONS=1 for more info.';
  1060. // Use a wasm runtime error, because a JS error might be seen as a foreign
  1061. // exception, which means we'd run destructors on it. We need the error to
  1062. // simply make the program stop.
  1063. var e = new WebAssembly.RuntimeError(what);
  1064. // Throw the error whether or not MODULARIZE is set because abort is used
  1065. // in code paths apart from instantiation where an exception is expected
  1066. // to be thrown when abort is called.
  1067. throw e;
  1068. }
  1069. // {{MEM_INITIALIZER}}
  1070. // include: memoryprofiler.js
  1071. // end include: memoryprofiler.js
  1072. // include: URIUtils.js
  1073. function hasPrefix(str, prefix) {
  1074. return String.prototype.startsWith ?
  1075. str.startsWith(prefix) :
  1076. str.indexOf(prefix) === 0;
  1077. }
  1078. // Prefix of data URIs emitted by SINGLE_FILE and related options.
  1079. var dataURIPrefix = 'data:application/octet-stream;base64,';
  1080. // Indicates whether filename is a base64 data URI.
  1081. function isDataURI(filename) {
  1082. return hasPrefix(filename, dataURIPrefix);
  1083. }
  1084. var fileURIPrefix = "file://";
  1085. // Indicates whether filename is delivered via file protocol (as opposed to http/https)
  1086. function isFileURI(filename) {
  1087. return hasPrefix(filename, fileURIPrefix);
  1088. }
  1089. // end include: URIUtils.js
  1090. var wasmBinaryFile = 'App.wasm';
  1091. if (!isDataURI(wasmBinaryFile)) {
  1092. wasmBinaryFile = locateFile(wasmBinaryFile);
  1093. }
  1094. function getBinary(file) {
  1095. try {
  1096. if (file == wasmBinaryFile && wasmBinary) {
  1097. return new Uint8Array(wasmBinary);
  1098. }
  1099. if (readBinary) {
  1100. return readBinary(file);
  1101. } else {
  1102. throw "both async and sync fetching of the wasm failed";
  1103. }
  1104. }
  1105. catch (err) {
  1106. abort(err);
  1107. }
  1108. }
  1109. function getBinaryPromise() {
  1110. // If we don't have the binary yet, try to to load it asynchronously.
  1111. // Fetch has some additional restrictions over XHR, like it can't be used on a file:// url.
  1112. // See https://github.com/github/fetch/pull/92#issuecomment-140665932
  1113. // Cordova or Electron apps are typically loaded from a file:// url.
  1114. // So use fetch if it is available and the url is not a file, otherwise fall back to XHR.
  1115. if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER)) {
  1116. if (typeof fetch === 'function'
  1117. && !isFileURI(wasmBinaryFile)
  1118. ) {
  1119. return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function(response) {
  1120. if (!response['ok']) {
  1121. throw "failed to load wasm binary file at '" + wasmBinaryFile + "'";
  1122. }
  1123. return response['arrayBuffer']();
  1124. }).catch(function () {
  1125. return getBinary(wasmBinaryFile);
  1126. });
  1127. }
  1128. else {
  1129. if (readAsync) {
  1130. // fetch is not available or url is file => try XHR (readAsync uses XHR internally)
  1131. return new Promise(function(resolve, reject) {
  1132. readAsync(wasmBinaryFile, function(response) { resolve(new Uint8Array(/** @type{!ArrayBuffer} */(response))) }, reject)
  1133. });
  1134. }
  1135. }
  1136. }
  1137. // Otherwise, getBinary should be able to get it synchronously
  1138. return Promise.resolve().then(function() { return getBinary(wasmBinaryFile); });
  1139. }
  1140. // Create the wasm instance.
  1141. // Receives the wasm imports, returns the exports.
  1142. function createWasm() {
  1143. // prepare imports
  1144. var info = {
  1145. 'env': asmLibraryArg,
  1146. 'wasi_snapshot_preview1': asmLibraryArg,
  1147. };
  1148. // Load the wasm module and create an instance of using native support in the JS engine.
  1149. // handle a generated wasm instance, receiving its exports and
  1150. // performing other necessary setup
  1151. /** @param {WebAssembly.Module=} module*/
  1152. function receiveInstance(instance, module) {
  1153. var exports = instance.exports;
  1154. exports = Asyncify.instrumentWasmExports(exports);
  1155. Module['asm'] = exports;
  1156. wasmMemory = Module['asm']['memory'];
  1157. updateGlobalBufferAndViews(wasmMemory.buffer);
  1158. wasmTable = Module['asm']['__indirect_function_table'];
  1159. removeRunDependency('wasm-instantiate');
  1160. }
  1161. // we can't run yet (except in a pthread, where we have a custom sync instantiator)
  1162. addRunDependency('wasm-instantiate');
  1163. function receiveInstantiatedSource(output) {
  1164. // 'output' is a WebAssemblyInstantiatedSource object which has both the module and instance.
  1165. // receiveInstance() will swap in the exports (to Module.asm) so they can be called
  1166. // 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.
  1167. // When the regression is fixed, can restore the above USE_PTHREADS-enabled path.
  1168. receiveInstance(output['instance']);
  1169. }
  1170. function instantiateArrayBuffer(receiver) {
  1171. return getBinaryPromise().then(function(binary) {
  1172. return WebAssembly.instantiate(binary, info);
  1173. }).then(receiver, function(reason) {
  1174. err('failed to asynchronously prepare wasm: ' + reason);
  1175. abort(reason);
  1176. });
  1177. }
  1178. // Prefer streaming instantiation if available.
  1179. function instantiateAsync() {
  1180. if (!wasmBinary &&
  1181. typeof WebAssembly.instantiateStreaming === 'function' &&
  1182. !isDataURI(wasmBinaryFile) &&
  1183. // Don't use streaming for file:// delivered objects in a webview, fetch them synchronously.
  1184. !isFileURI(wasmBinaryFile) &&
  1185. typeof fetch === 'function') {
  1186. return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function (response) {
  1187. var result = WebAssembly.instantiateStreaming(response, info);
  1188. return result.then(receiveInstantiatedSource, function(reason) {
  1189. // We expect the most common failure cause to be a bad MIME type for the binary,
  1190. // in which case falling back to ArrayBuffer instantiation should work.
  1191. err('wasm streaming compile failed: ' + reason);
  1192. err('falling back to ArrayBuffer instantiation');
  1193. return instantiateArrayBuffer(receiveInstantiatedSource);
  1194. });
  1195. });
  1196. } else {
  1197. return instantiateArrayBuffer(receiveInstantiatedSource);
  1198. }
  1199. }
  1200. // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback
  1201. // to manually instantiate the Wasm module themselves. This allows pages to run the instantiation parallel
  1202. // to any other async startup actions they are performing.
  1203. if (Module['instantiateWasm']) {
  1204. try {
  1205. var exports = Module['instantiateWasm'](info, receiveInstance);
  1206. exports = Asyncify.instrumentWasmExports(exports);
  1207. return exports;
  1208. } catch(e) {
  1209. err('Module.instantiateWasm callback failed with error: ' + e);
  1210. return false;
  1211. }
  1212. }
  1213. instantiateAsync();
  1214. return {}; // no exports yet; we'll fill them in later
  1215. }
  1216. // Globals used by JS i64 conversions (see makeSetValue)
  1217. var tempDouble;
  1218. var tempI64;
  1219. // === Body ===
  1220. var ASM_CONSTS = {
  1221. 20020: function() {if ((window.AudioContext || window.webkitAudioContext) === undefined) { return 0; } if (typeof(miniaudio) === 'undefined') { miniaudio = {}; miniaudio.devices = []; miniaudio.track_device = function(device) { for (var iDevice = 0; iDevice < miniaudio.devices.length; ++iDevice) { if (miniaudio.devices[iDevice] == null) { miniaudio.devices[iDevice] = device; return iDevice; } } miniaudio.devices.push(device); return miniaudio.devices.length - 1; }; miniaudio.untrack_device_by_index = function(deviceIndex) { miniaudio.devices[deviceIndex] = null; while (miniaudio.devices.length > 0) { if (miniaudio.devices[miniaudio.devices.length-1] == null) { miniaudio.devices.pop(); } else { break; } } }; miniaudio.untrack_device = function(device) { for (var iDevice = 0; iDevice < miniaudio.devices.length; ++iDevice) { if (miniaudio.devices[iDevice] == device) { return miniaudio.untrack_device_by_index(iDevice); } } }; miniaudio.get_device_by_index = function(deviceIndex) { return miniaudio.devices[deviceIndex]; }; } return 1;},
  1222. 21260: function() {return (navigator.mediaDevices !== undefined && navigator.mediaDevices.getUserMedia !== undefined);},
  1223. 21401: function() {try { var temp = new (window.AudioContext || window.webkitAudioContext)(); var sampleRate = temp.sampleRate; temp.close(); return sampleRate; } catch(e) { return 0; }},
  1224. 21627: function($0, $1, $2, $3, $4) {var channels = $0; var sampleRate = $1; var bufferSize = $2; var isCapture = $3; var pDevice = $4; if (typeof(miniaudio) === 'undefined') { return -1; } var device = {}; device.webaudio = new (window.AudioContext || window.webkitAudioContext)({sampleRate:sampleRate}); device.webaudio.suspend(); device.intermediaryBufferSizeInBytes = channels * bufferSize * 4; device.intermediaryBuffer = Module._malloc(device.intermediaryBufferSizeInBytes); device.intermediaryBufferView = new Float32Array(Module.HEAPF32.buffer, device.intermediaryBuffer, device.intermediaryBufferSizeInBytes); device.scriptNode = device.webaudio.createScriptProcessor(bufferSize, channels, channels); if (isCapture) { device.scriptNode.onaudioprocess = function(e) { if (device.intermediaryBuffer === undefined) { return; } for (var iChannel = 0; iChannel < e.outputBuffer.numberOfChannels; ++iChannel) { e.outputBuffer.getChannelData(iChannel).fill(0.0); } var sendSilence = false; if (device.streamNode === undefined) { sendSilence = true; } if (e.inputBuffer.numberOfChannels != channels) { console.log("Capture: Channel count mismatch. " + e.inputBufer.numberOfChannels + " != " + channels + ". Sending silence."); sendSilence = true; } var totalFramesProcessed = 0; while (totalFramesProcessed < e.inputBuffer.length) { var framesRemaining = e.inputBuffer.length - totalFramesProcessed; var framesToProcess = framesRemaining; if (framesToProcess > (device.intermediaryBufferSizeInBytes/channels/4)) { framesToProcess = (device.intermediaryBufferSizeInBytes/channels/4); } if (sendSilence) { device.intermediaryBufferView.fill(0.0); } else { for (var iFrame = 0; iFrame < framesToProcess; ++iFrame) { for (var iChannel = 0; iChannel < e.inputBuffer.numberOfChannels; ++iChannel) { device.intermediaryBufferView[iFrame*channels + iChannel] = e.inputBuffer.getChannelData(iChannel)[totalFramesProcessed + iFrame]; } } } ccall("ma_device_process_pcm_frames_capture__webaudio", "undefined", ["number", "number", "number"], [pDevice, framesToProcess, device.intermediaryBuffer]); totalFramesProcessed += framesToProcess; } }; navigator.mediaDevices.getUserMedia({audio:true, video:false}) .then(function(stream) { device.streamNode = device.webaudio.createMediaStreamSource(stream); device.streamNode.connect(device.scriptNode); device.scriptNode.connect(device.webaudio.destination); }) .catch(function(error) { device.scriptNode.connect(device.webaudio.destination); }); } else { device.scriptNode.onaudioprocess = function(e) { if (device.intermediaryBuffer === undefined) { return; } var outputSilence = false; if (e.outputBuffer.numberOfChannels != channels) { console.log("Playback: Channel count mismatch. " + e.outputBufer.numberOfChannels + " != " + channels + ". Outputting silence."); outputSilence = true; return; } var totalFramesProcessed = 0; while (totalFramesProcessed < e.outputBuffer.length) { var framesRemaining = e.outputBuffer.length - totalFramesProcessed; var framesToProcess = framesRemaining; if (framesToProcess > (device.intermediaryBufferSizeInBytes/channels/4)) { framesToProcess = (device.intermediaryBufferSizeInBytes/channels/4); } ccall("ma_device_process_pcm_frames_playback__webaudio", "undefined", ["number", "number", "number"], [pDevice, framesToProcess, device.intermediaryBuffer]); if (outputSilence) { for (var iChannel = 0; iChannel < e.outputBuffer.numberOfChannels; ++iChannel) { e.outputBuffer.getChannelData(iChannel).fill(0.0); } } else { for (var iChannel = 0; iChannel < e.outputBuffer.numberOfChannels; ++iChannel) { for (var iFrame = 0; iFrame < framesToProcess; ++iFrame) { e.outputBuffer.getChannelData(iChannel)[totalFramesProcessed + iFrame] = device.intermediaryBufferView[iFrame*channels + iChannel]; } } } totalFramesProcessed += framesToProcess; } }; device.scriptNode.connect(device.webaudio.destination); } return miniaudio.track_device(device);},
  1225. 25511: function($0) {return miniaudio.get_device_by_index($0).webaudio.sampleRate;},
  1226. 25613: function($0) {var device = miniaudio.get_device_by_index($0); if (device.scriptNode !== undefined) { device.scriptNode.onaudioprocess = function(e) {}; device.scriptNode.disconnect(); device.scriptNode = undefined; } if (device.streamNode !== undefined) { device.streamNode.disconnect(); device.streamNode = undefined; } device.webaudio.close(); device.webaudio = undefined; if (device.intermediaryBuffer !== undefined) { Module._free(device.intermediaryBuffer); device.intermediaryBuffer = undefined; device.intermediaryBufferView = undefined; device.intermediaryBufferSizeInBytes = undefined; } miniaudio.untrack_device_by_index($0);},
  1227. 26292: function($0) {miniaudio.get_device_by_index($0).webaudio.resume();},
  1228. 26374: function($0) {miniaudio.get_device_by_index($0).webaudio.suspend();}
  1229. };
  1230. function callRuntimeCallbacks(callbacks) {
  1231. while(callbacks.length > 0) {
  1232. var callback = callbacks.shift();
  1233. if (typeof callback == 'function') {
  1234. callback(Module); // Pass the module as the first argument.
  1235. continue;
  1236. }
  1237. var func = callback.func;
  1238. if (typeof func === 'number') {
  1239. if (callback.arg === undefined) {
  1240. (function() { dynCall_v.call(null, func); })();
  1241. } else {
  1242. (function(a1) { dynCall_vi.apply(null, [func, a1]); })(callback.arg);
  1243. }
  1244. } else {
  1245. func(callback.arg === undefined ? null : callback.arg);
  1246. }
  1247. }
  1248. }
  1249. function demangle(func) {
  1250. return func;
  1251. }
  1252. function demangleAll(text) {
  1253. var regex =
  1254. /\b_Z[\w\d_]+/g;
  1255. return text.replace(regex,
  1256. function(x) {
  1257. var y = demangle(x);
  1258. return x === y ? x : (y + ' [' + x + ']');
  1259. });
  1260. }
  1261. function jsStackTrace() {
  1262. var error = new Error();
  1263. if (!error.stack) {
  1264. // IE10+ special cases: It does have callstack info, but it is only populated if an Error object is thrown,
  1265. // so try that as a special-case.
  1266. try {
  1267. throw new Error();
  1268. } catch(e) {
  1269. error = e;
  1270. }
  1271. if (!error.stack) {
  1272. return '(no stack trace available)';
  1273. }
  1274. }
  1275. return error.stack.toString();
  1276. }
  1277. function stackTrace() {
  1278. var js = jsStackTrace();
  1279. if (Module['extraStackTrace']) js += '\n' + Module['extraStackTrace']();
  1280. return demangleAll(js);
  1281. }
  1282. function ___assert_fail(condition, filename, line, func) {
  1283. abort('Assertion failed: ' + UTF8ToString(condition) + ', at: ' + [filename ? UTF8ToString(filename) : 'unknown filename', line, func ? UTF8ToString(func) : 'unknown function']);
  1284. }
  1285. function _emscripten_asm_const_int(code, sigPtr, argbuf) {
  1286. var args = readAsmConstArgs(sigPtr, argbuf);
  1287. return ASM_CONSTS[code].apply(null, args);
  1288. }
  1289. var JSEvents={inEventHandler:0,removeAllEventListeners:function() {
  1290. for(var i = JSEvents.eventHandlers.length-1; i >= 0; --i) {
  1291. JSEvents._removeHandler(i);
  1292. }
  1293. JSEvents.eventHandlers = [];
  1294. JSEvents.deferredCalls = [];
  1295. },registerRemoveEventListeners:function() {
  1296. if (!JSEvents.removeEventListenersRegistered) {
  1297. __ATEXIT__.push(JSEvents.removeAllEventListeners);
  1298. JSEvents.removeEventListenersRegistered = true;
  1299. }
  1300. },deferredCalls:[],deferCall:function(targetFunction, precedence, argsList) {
  1301. function arraysHaveEqualContent(arrA, arrB) {
  1302. if (arrA.length != arrB.length) return false;
  1303. for(var i in arrA) {
  1304. if (arrA[i] != arrB[i]) return false;
  1305. }
  1306. return true;
  1307. }
  1308. // Test if the given call was already queued, and if so, don't add it again.
  1309. for(var i in JSEvents.deferredCalls) {
  1310. var call = JSEvents.deferredCalls[i];
  1311. if (call.targetFunction == targetFunction && arraysHaveEqualContent(call.argsList, argsList)) {
  1312. return;
  1313. }
  1314. }
  1315. JSEvents.deferredCalls.push({
  1316. targetFunction: targetFunction,
  1317. precedence: precedence,
  1318. argsList: argsList
  1319. });
  1320. JSEvents.deferredCalls.sort(function(x,y) { return x.precedence < y.precedence; });
  1321. },removeDeferredCalls:function(targetFunction) {
  1322. for(var i = 0; i < JSEvents.deferredCalls.length; ++i) {
  1323. if (JSEvents.deferredCalls[i].targetFunction == targetFunction) {
  1324. JSEvents.deferredCalls.splice(i, 1);
  1325. --i;
  1326. }
  1327. }
  1328. },canPerformEventHandlerRequests:function() {
  1329. return JSEvents.inEventHandler && JSEvents.currentEventHandler.allowsDeferredCalls;
  1330. },runDeferredCalls:function() {
  1331. if (!JSEvents.canPerformEventHandlerRequests()) {
  1332. return;
  1333. }
  1334. for(var i = 0; i < JSEvents.deferredCalls.length; ++i) {
  1335. var call = JSEvents.deferredCalls[i];
  1336. JSEvents.deferredCalls.splice(i, 1);
  1337. --i;
  1338. call.targetFunction.apply(null, call.argsList);
  1339. }
  1340. },eventHandlers:[],removeAllHandlersOnTarget:function(target, eventTypeString) {
  1341. for(var i = 0; i < JSEvents.eventHandlers.length; ++i) {
  1342. if (JSEvents.eventHandlers[i].target == target &&
  1343. (!eventTypeString || eventTypeString == JSEvents.eventHandlers[i].eventTypeString)) {
  1344. JSEvents._removeHandler(i--);
  1345. }
  1346. }
  1347. },_removeHandler:function(i) {
  1348. var h = JSEvents.eventHandlers[i];
  1349. h.target.removeEventListener(h.eventTypeString, h.eventListenerFunc, h.useCapture);
  1350. JSEvents.eventHandlers.splice(i, 1);
  1351. },registerOrRemoveHandler:function(eventHandler) {
  1352. var jsEventHandler = function jsEventHandler(event) {
  1353. // Increment nesting count for the event handler.
  1354. ++JSEvents.inEventHandler;
  1355. JSEvents.currentEventHandler = eventHandler;
  1356. // Process any old deferred calls the user has placed.
  1357. JSEvents.runDeferredCalls();
  1358. // Process the actual event, calls back to user C code handler.
  1359. eventHandler.handlerFunc(event);
  1360. // Process any new deferred calls that were placed right now from this event handler.
  1361. JSEvents.runDeferredCalls();
  1362. // Out of event handler - restore nesting count.
  1363. --JSEvents.inEventHandler;
  1364. };
  1365. if (eventHandler.callbackfunc) {
  1366. eventHandler.eventListenerFunc = jsEventHandler;
  1367. eventHandler.target.addEventListener(eventHandler.eventTypeString, jsEventHandler, eventHandler.useCapture);
  1368. JSEvents.eventHandlers.push(eventHandler);
  1369. JSEvents.registerRemoveEventListeners();
  1370. } else {
  1371. for(var i = 0; i < JSEvents.eventHandlers.length; ++i) {
  1372. if (JSEvents.eventHandlers[i].target == eventHandler.target
  1373. && JSEvents.eventHandlers[i].eventTypeString == eventHandler.eventTypeString) {
  1374. JSEvents._removeHandler(i--);
  1375. }
  1376. }
  1377. }
  1378. },getNodeNameForTarget:function(target) {
  1379. if (!target) return '';
  1380. if (target == window) return '#window';
  1381. if (target == screen) return '#screen';
  1382. return (target && target.nodeName) ? target.nodeName : '';
  1383. },fullscreenEnabled:function() {
  1384. return document.fullscreenEnabled
  1385. // Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitFullscreenEnabled.
  1386. // TODO: If Safari at some point ships with unprefixed version, update the version check above.
  1387. || document.webkitFullscreenEnabled
  1388. ;
  1389. }};
  1390. function setLetterbox(element, topBottom, leftRight) {
  1391. // Cannot use margin to specify letterboxes in FF or Chrome, since those ignore margins in fullscreen mode.
  1392. element.style.paddingLeft = element.style.paddingRight = leftRight + 'px';
  1393. element.style.paddingTop = element.style.paddingBottom = topBottom + 'px';
  1394. }
  1395. function hideEverythingExceptGivenElement(onlyVisibleElement) {
  1396. var child = onlyVisibleElement;
  1397. var parent = child.parentNode;
  1398. var hiddenElements = [];
  1399. while (child != document.body) {
  1400. var children = parent.children;
  1401. for (var i = 0; i < children.length; ++i) {
  1402. if (children[i] != child) {
  1403. hiddenElements.push({ node: children[i], displayState: children[i].style.display });
  1404. children[i].style.display = 'none';
  1405. }
  1406. }
  1407. child = parent;
  1408. parent = parent.parentNode;
  1409. }
  1410. return hiddenElements;
  1411. }
  1412. var restoreOldWindowedStyle=null;
  1413. function maybeCStringToJsString(cString) {
  1414. // "cString > 2" checks if the input is a number, and isn't of the special
  1415. // values we accept here, EMSCRIPTEN_EVENT_TARGET_* (which map to 0, 1, 2).
  1416. // In other words, if cString > 2 then it's a pointer to a valid place in
  1417. // memory, and points to a C string.
  1418. return cString > 2 ? UTF8ToString(cString) : cString;
  1419. }
  1420. var specialHTMLTargets=[0, typeof document !== 'undefined' ? document : 0, typeof window !== 'undefined' ? window : 0];
  1421. function findEventTarget(target) {
  1422. target = maybeCStringToJsString(target);
  1423. var domElement = specialHTMLTargets[target] || (typeof document !== 'undefined' ? document.querySelector(target) : undefined);
  1424. return domElement;
  1425. }
  1426. function findCanvasEventTarget(target) { return findEventTarget(target); }
  1427. function _emscripten_get_canvas_element_size(target, width, height) {
  1428. var canvas = findCanvasEventTarget(target);
  1429. if (!canvas) return -4;
  1430. HEAP32[((width)>>2)] = canvas.width;
  1431. HEAP32[((height)>>2)] = canvas.height;
  1432. }
  1433. function getCanvasElementSize(target) {
  1434. var stackTop = stackSave();
  1435. var w = stackAlloc(8);
  1436. var h = w + 4;
  1437. var targetInt = stackAlloc(target.id.length+1);
  1438. stringToUTF8(target.id, targetInt, target.id.length+1);
  1439. var ret = _emscripten_get_canvas_element_size(targetInt, w, h);
  1440. var size = [HEAP32[((w)>>2)], HEAP32[((h)>>2)]];
  1441. stackRestore(stackTop);
  1442. return size;
  1443. }
  1444. function _emscripten_set_canvas_element_size(target, width, height) {
  1445. var canvas = findCanvasEventTarget(target);
  1446. if (!canvas) return -4;
  1447. canvas.width = width;
  1448. canvas.height = height;
  1449. return 0;
  1450. }
  1451. function setCanvasElementSize(target, width, height) {
  1452. if (!target.controlTransferredOffscreen) {
  1453. target.width = width;
  1454. target.height = height;
  1455. } else {
  1456. // This function is being called from high-level JavaScript code instead of asm.js/Wasm,
  1457. // and it needs to synchronously proxy over to another thread, so marshal the string onto the heap to do the call.
  1458. var stackTop = stackSave();
  1459. var targetInt = stackAlloc(target.id.length+1);
  1460. stringToUTF8(target.id, targetInt, target.id.length+1);
  1461. _emscripten_set_canvas_element_size(targetInt, width, height);
  1462. stackRestore(stackTop);
  1463. }
  1464. }
  1465. function registerRestoreOldStyle(canvas) {
  1466. var canvasSize = getCanvasElementSize(canvas);
  1467. var oldWidth = canvasSize[0];
  1468. var oldHeight = canvasSize[1];
  1469. var oldCssWidth = canvas.style.width;
  1470. var oldCssHeight = canvas.style.height;
  1471. var oldBackgroundColor = canvas.style.backgroundColor; // Chrome reads color from here.
  1472. var oldDocumentBackgroundColor = document.body.style.backgroundColor; // IE11 reads color from here.
  1473. // Firefox always has black background color.
  1474. var oldPaddingLeft = canvas.style.paddingLeft; // Chrome, FF, Safari
  1475. var oldPaddingRight = canvas.style.paddingRight;
  1476. var oldPaddingTop = canvas.style.paddingTop;
  1477. var oldPaddingBottom = canvas.style.paddingBottom;
  1478. var oldMarginLeft = canvas.style.marginLeft; // IE11
  1479. var oldMarginRight = canvas.style.marginRight;
  1480. var oldMarginTop = canvas.style.marginTop;
  1481. var oldMarginBottom = canvas.style.marginBottom;
  1482. var oldDocumentBodyMargin = document.body.style.margin;
  1483. var oldDocumentOverflow = document.documentElement.style.overflow; // Chrome, Firefox
  1484. var oldDocumentScroll = document.body.scroll; // IE
  1485. var oldImageRendering = canvas.style.imageRendering;
  1486. function restoreOldStyle() {
  1487. var fullscreenElement = document.fullscreenElement
  1488. || document.webkitFullscreenElement
  1489. || document.msFullscreenElement
  1490. ;
  1491. if (!fullscreenElement) {
  1492. document.removeEventListener('fullscreenchange', restoreOldStyle);
  1493. // Unprefixed Fullscreen API shipped in Chromium 71 (https://bugs.chromium.org/p/chromium/issues/detail?id=383813)
  1494. // 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.
  1495. document.removeEventListener('webkitfullscreenchange', restoreOldStyle);
  1496. setCanvasElementSize(canvas, oldWidth, oldHeight);
  1497. canvas.style.width = oldCssWidth;
  1498. canvas.style.height = oldCssHeight;
  1499. canvas.style.backgroundColor = oldBackgroundColor; // Chrome
  1500. // IE11 hack: assigning 'undefined' or an empty string to document.body.style.backgroundColor has no effect, so first assign back the default color
  1501. // before setting the undefined value. Setting undefined value is also important, or otherwise we would later treat that as something that the user
  1502. // had explicitly set so subsequent fullscreen transitions would not set background color properly.
  1503. if (!oldDocumentBackgroundColor) document.body.style.backgroundColor = 'white';
  1504. document.body.style.backgroundColor = oldDocumentBackgroundColor; // IE11
  1505. canvas.style.paddingLeft = oldPaddingLeft; // Chrome, FF, Safari
  1506. canvas.style.paddingRight = oldPaddingRight;
  1507. canvas.style.paddingTop = oldPaddingTop;
  1508. canvas.style.paddingBottom = oldPaddingBottom;
  1509. canvas.style.marginLeft = oldMarginLeft; // IE11
  1510. canvas.style.marginRight = oldMarginRight;
  1511. canvas.style.marginTop = oldMarginTop;
  1512. canvas.style.marginBottom = oldMarginBottom;
  1513. document.body.style.margin = oldDocumentBodyMargin;
  1514. document.documentElement.style.overflow = oldDocumentOverflow; // Chrome, Firefox
  1515. document.body.scroll = oldDocumentScroll; // IE
  1516. canvas.style.imageRendering = oldImageRendering;
  1517. if (canvas.GLctxObject) canvas.GLctxObject.GLctx.viewport(0, 0, oldWidth, oldHeight);
  1518. if (currentFullscreenStrategy.canvasResizedCallback) {
  1519. (function(a1, a2, a3) { dynCall_iiii.apply(null, [currentFullscreenStrategy.canvasResizedCallback, a1, a2, a3]); })(37, 0, currentFullscreenStrategy.canvasResizedCallbackUserData);
  1520. }
  1521. }
  1522. }
  1523. document.addEventListener('fullscreenchange', restoreOldStyle);
  1524. // Unprefixed Fullscreen API shipped in Chromium 71 (https://bugs.chromium.org/p/chromium/issues/detail?id=383813)
  1525. // 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.
  1526. document.addEventListener('webkitfullscreenchange', restoreOldStyle);
  1527. return restoreOldStyle;
  1528. }
  1529. function restoreHiddenElements(hiddenElements) {
  1530. for (var i = 0; i < hiddenElements.length; ++i) {
  1531. hiddenElements[i].node.style.display = hiddenElements[i].displayState;
  1532. }
  1533. }
  1534. var currentFullscreenStrategy={};
  1535. /** @suppress {checkTypes} */
  1536. function jstoi_q(str) {
  1537. return parseInt(str);
  1538. }
  1539. function softFullscreenResizeWebGLRenderTarget() {
  1540. var dpr = devicePixelRatio;
  1541. var inHiDPIFullscreenMode = currentFullscreenStrategy.canvasResolutionScaleMode == 2;
  1542. var inAspectRatioFixedFullscreenMode = currentFullscreenStrategy.scaleMode == 2;
  1543. var inPixelPerfectFullscreenMode = currentFullscreenStrategy.canvasResolutionScaleMode != 0;
  1544. var inCenteredWithoutScalingFullscreenMode = currentFullscreenStrategy.scaleMode == 3;
  1545. var screenWidth = inHiDPIFullscreenMode ? Math.round(innerWidth*dpr) : innerWidth;
  1546. var screenHeight = inHiDPIFullscreenMode ? Math.round(innerHeight*dpr) : innerHeight;
  1547. var w = screenWidth;
  1548. var h = screenHeight;
  1549. var canvas = currentFullscreenStrategy.target;
  1550. var canvasSize = getCanvasElementSize(canvas);
  1551. var x = canvasSize[0];
  1552. var y = canvasSize[1];
  1553. var topMargin;
  1554. if (inAspectRatioFixedFullscreenMode) {
  1555. if (w*y < x*h) h = (w * y / x) | 0;
  1556. else if (w*y > x*h) w = (h * x / y) | 0;
  1557. topMargin = ((screenHeight - h) / 2) | 0;
  1558. }
  1559. if (inPixelPerfectFullscreenMode) {
  1560. setCanvasElementSize(canvas, w, h);
  1561. if (canvas.GLctxObject) canvas.GLctxObject.GLctx.viewport(0, 0, w, h);
  1562. }
  1563. // Back to CSS pixels.
  1564. if (inHiDPIFullscreenMode) {
  1565. topMargin /= dpr;
  1566. w /= dpr;
  1567. h /= dpr;
  1568. // Round to nearest 4 digits of precision.
  1569. w = Math.round(w*1e4)/1e4;
  1570. h = Math.round(h*1e4)/1e4;
  1571. topMargin = Math.round(topMargin*1e4)/1e4;
  1572. }
  1573. if (inCenteredWithoutScalingFullscreenMode) {
  1574. var t = (innerHeight - jstoi_q(canvas.style.height)) / 2;
  1575. var b = (innerWidth - jstoi_q(canvas.style.width)) / 2;
  1576. setLetterbox(canvas, t, b);
  1577. } else {
  1578. canvas.style.width = w + 'px';
  1579. canvas.style.height = h + 'px';
  1580. var b = (innerWidth - w) / 2;
  1581. setLetterbox(canvas, topMargin, b);
  1582. }
  1583. if (!inCenteredWithoutScalingFullscreenMode && currentFullscreenStrategy.canvasResizedCallback) {
  1584. (function(a1, a2, a3) { dynCall_iiii.apply(null, [currentFullscreenStrategy.canvasResizedCallback, a1, a2, a3]); })(37, 0, currentFullscreenStrategy.canvasResizedCallbackUserData);
  1585. }
  1586. }
  1587. function getBoundingClientRect(e) {
  1588. return specialHTMLTargets.indexOf(e) < 0 ? e.getBoundingClientRect() : {'left':0,'top':0};
  1589. }
  1590. function _JSEvents_resizeCanvasForFullscreen(target, strategy) {
  1591. var restoreOldStyle = registerRestoreOldStyle(target);
  1592. var cssWidth = strategy.softFullscreen ? innerWidth : screen.width;
  1593. var cssHeight = strategy.softFullscreen ? innerHeight : screen.height;
  1594. var rect = getBoundingClientRect(target);
  1595. var windowedCssWidth = rect.width;
  1596. var windowedCssHeight = rect.height;
  1597. var canvasSize = getCanvasElementSize(target);
  1598. var windowedRttWidth = canvasSize[0];
  1599. var windowedRttHeight = canvasSize[1];
  1600. if (strategy.scaleMode == 3) {
  1601. setLetterbox(target, (cssHeight - windowedCssHeight) / 2, (cssWidth - windowedCssWidth) / 2);
  1602. cssWidth = windowedCssWidth;
  1603. cssHeight = windowedCssHeight;
  1604. } else if (strategy.scaleMode == 2) {
  1605. if (cssWidth*windowedRttHeight < windowedRttWidth*cssHeight) {
  1606. var desiredCssHeight = windowedRttHeight * cssWidth / windowedRttWidth;
  1607. setLetterbox(target, (cssHeight - desiredCssHeight) / 2, 0);
  1608. cssHeight = desiredCssHeight;
  1609. } else {
  1610. var desiredCssWidth = windowedRttWidth * cssHeight / windowedRttHeight;
  1611. setLetterbox(target, 0, (cssWidth - desiredCssWidth) / 2);
  1612. cssWidth = desiredCssWidth;
  1613. }
  1614. }
  1615. // If we are adding padding, must choose a background color or otherwise Chrome will give the
  1616. // padding a default white color. Do it only if user has not customized their own background color.
  1617. if (!target.style.backgroundColor) target.style.backgroundColor = 'black';
  1618. // IE11 does the same, but requires the color to be set in the document body.
  1619. if (!document.body.style.backgroundColor) document.body.style.backgroundColor = 'black'; // IE11
  1620. // Firefox always shows black letterboxes independent of style color.
  1621. target.style.width = cssWidth + 'px';
  1622. target.style.height = cssHeight + 'px';
  1623. if (strategy.filteringMode == 1) {
  1624. target.style.imageRendering = 'optimizeSpeed';
  1625. target.style.imageRendering = '-moz-crisp-edges';
  1626. target.style.imageRendering = '-o-crisp-edges';
  1627. target.style.imageRendering = '-webkit-optimize-contrast';
  1628. target.style.imageRendering = 'optimize-contrast';
  1629. target.style.imageRendering = 'crisp-edges';
  1630. target.style.imageRendering = 'pixelated';
  1631. }
  1632. var dpiScale = (strategy.canvasResolutionScaleMode == 2) ? devicePixelRatio : 1;
  1633. if (strategy.canvasResolutionScaleMode != 0) {
  1634. var newWidth = (cssWidth * dpiScale)|0;
  1635. var newHeight = (cssHeight * dpiScale)|0;
  1636. setCanvasElementSize(target, newWidth, newHeight);
  1637. if (target.GLctxObject) target.GLctxObject.GLctx.viewport(0, 0, newWidth, newHeight);
  1638. }
  1639. return restoreOldStyle;
  1640. }
  1641. function _emscripten_enter_soft_fullscreen(target, fullscreenStrategy) {
  1642. target = findEventTarget(target);
  1643. if (!target) return -4;
  1644. var strategy = {
  1645. scaleMode: HEAP32[((fullscreenStrategy)>>2)],
  1646. canvasResolutionScaleMode: HEAP32[(((fullscreenStrategy)+(4))>>2)],
  1647. filteringMode: HEAP32[(((fullscreenStrategy)+(8))>>2)],
  1648. canvasResizedCallback: HEAP32[(((fullscreenStrategy)+(12))>>2)],
  1649. canvasResizedCallbackUserData: HEAP32[(((fullscreenStrategy)+(16))>>2)],
  1650. target: target,
  1651. softFullscreen: true
  1652. };
  1653. var restoreOldStyle = _JSEvents_resizeCanvasForFullscreen(target, strategy);
  1654. document.documentElement.style.overflow = 'hidden'; // Firefox, Chrome
  1655. document.body.scroll = "no"; // IE11
  1656. document.body.style.margin = '0px'; // Override default document margin area on all browsers.
  1657. var hiddenElements = hideEverythingExceptGivenElement(target);
  1658. function restoreWindowedState() {
  1659. restoreOldStyle();
  1660. restoreHiddenElements(hiddenElements);
  1661. removeEventListener('resize', softFullscreenResizeWebGLRenderTarget);
  1662. if (strategy.canvasResizedCallback) {
  1663. (function(a1, a2, a3) { dynCall_iiii.apply(null, [strategy.canvasResizedCallback, a1, a2, a3]); })(37, 0, strategy.canvasResizedCallbackUserData);
  1664. }
  1665. currentFullscreenStrategy = 0;
  1666. }
  1667. restoreOldWindowedStyle = restoreWindowedState;
  1668. currentFullscreenStrategy = strategy;
  1669. addEventListener('resize', softFullscreenResizeWebGLRenderTarget);
  1670. // Inform the caller that the canvas size has changed.
  1671. if (strategy.canvasResizedCallback) {
  1672. (function(a1, a2, a3) { dynCall_iiii.apply(null, [strategy.canvasResizedCallback, a1, a2, a3]); })(37, 0, strategy.canvasResizedCallbackUserData);
  1673. }
  1674. return 0;
  1675. }
  1676. function _JSEvents_requestFullscreen(target, strategy) {
  1677. // EMSCRIPTEN_FULLSCREEN_SCALE_DEFAULT + EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE is a mode where no extra logic is performed to the DOM elements.
  1678. if (strategy.scaleMode != 0 || strategy.canvasResolutionScaleMode != 0) {
  1679. _JSEvents_resizeCanvasForFullscreen(target, strategy);
  1680. }
  1681. if (target.requestFullscreen) {
  1682. target.requestFullscreen();
  1683. } else if (target.webkitRequestFullscreen) {
  1684. target.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
  1685. } else {
  1686. return JSEvents.fullscreenEnabled() ? -3 : -1;
  1687. }
  1688. currentFullscreenStrategy = strategy;
  1689. if (strategy.canvasResizedCallback) {
  1690. (function(a1, a2, a3) { dynCall_iiii.apply(null, [strategy.canvasResizedCallback, a1, a2, a3]); })(37, 0, strategy.canvasResizedCallbackUserData);
  1691. }
  1692. return 0;
  1693. }
  1694. function _emscripten_exit_fullscreen() {
  1695. if (!JSEvents.fullscreenEnabled()) return -1;
  1696. // Make sure no queued up calls will fire after this.
  1697. JSEvents.removeDeferredCalls(_JSEvents_requestFullscreen);
  1698. var d = specialHTMLTargets[1];
  1699. if (d.exitFullscreen) {
  1700. d.fullscreenElement && d.exitFullscreen();
  1701. } else if (d.webkitExitFullscreen) {
  1702. d.webkitFullscreenElement && d.webkitExitFullscreen();
  1703. } else {
  1704. return -1;
  1705. }
  1706. return 0;
  1707. }
  1708. function _emscripten_get_element_css_size(target, width, height) {
  1709. target = findEventTarget(target);
  1710. if (!target) return -4;
  1711. var rect = getBoundingClientRect(target);
  1712. HEAPF64[((width)>>3)] = rect.width;
  1713. HEAPF64[((height)>>3)] = rect.height;
  1714. return 0;
  1715. }
  1716. function fillPointerlockChangeEventData(eventStruct) {
  1717. var pointerLockElement = document.pointerLockElement || document.mozPointerLockElement || document.webkitPointerLockElement || document.msPointerLockElement;
  1718. var isPointerlocked = !!pointerLockElement;
  1719. /** @suppress {checkTypes} */
  1720. HEAP32[((eventStruct)>>2)] = isPointerlocked;
  1721. var nodeName = JSEvents.getNodeNameForTarget(pointerLockElement);
  1722. var id = (pointerLockElement && pointerLockElement.id) ? pointerLockElement.id : '';
  1723. stringToUTF8(nodeName, eventStruct + 4, 128);
  1724. stringToUTF8(id, eventStruct + 132, 128);
  1725. }
  1726. /** @suppress {missingProperties} */
  1727. function _emscripten_get_pointerlock_status(pointerlockStatus) {
  1728. if (pointerlockStatus) fillPointerlockChangeEventData(pointerlockStatus);
  1729. if (!document.body || (!document.body.requestPointerLock && !document.body.mozRequestPointerLock && !document.body.webkitRequestPointerLock && !document.body.msRequestPointerLock)) {
  1730. return -1;
  1731. }
  1732. return 0;
  1733. }
  1734. function _emscripten_memcpy_big(dest, src, num) {
  1735. HEAPU8.copyWithin(dest, src, src + num);
  1736. }
  1737. function _emscripten_performance_now() {
  1738. return performance.now();
  1739. }
  1740. function _emscripten_get_heap_size() {
  1741. return HEAPU8.length;
  1742. }
  1743. function abortOnCannotGrowMemory(requestedSize) {
  1744. abort('OOM');
  1745. }
  1746. function _emscripten_resize_heap(requestedSize) {
  1747. requestedSize = requestedSize >>> 0;
  1748. abortOnCannotGrowMemory(requestedSize);
  1749. }
  1750. function fillMouseEventData(eventStruct, e, target) {
  1751. var idx = eventStruct >> 2;
  1752. HEAP32[idx + 0] = e.screenX;
  1753. HEAP32[idx + 1] = e.screenY;
  1754. HEAP32[idx + 2] = e.clientX;
  1755. HEAP32[idx + 3] = e.clientY;
  1756. HEAP32[idx + 4] = e.ctrlKey;
  1757. HEAP32[idx + 5] = e.shiftKey;
  1758. HEAP32[idx + 6] = e.altKey;
  1759. HEAP32[idx + 7] = e.metaKey;
  1760. HEAP16[idx*2 + 16] = e.button;
  1761. HEAP16[idx*2 + 17] = e.buttons;
  1762. HEAP32[idx + 9] = e["movementX"]
  1763. ;
  1764. HEAP32[idx + 10] = e["movementY"]
  1765. ;
  1766. var rect = getBoundingClientRect(target);
  1767. HEAP32[idx + 11] = e.clientX - rect.left;
  1768. HEAP32[idx + 12] = e.clientY - rect.top;
  1769. }
  1770. function registerMouseEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {
  1771. if (!JSEvents.mouseEvent) JSEvents.mouseEvent = _malloc( 64 );
  1772. target = findEventTarget(target);
  1773. var mouseEventHandlerFunc = function(ev) {
  1774. var e = ev || event;
  1775. // TODO: Make this access thread safe, or this could update live while app is reading it.
  1776. fillMouseEventData(JSEvents.mouseEvent, e, target);
  1777. if ((function(a1, a2, a3) { dynCall_iiii.apply(null, [callbackfunc, a1, a2, a3]); })(eventTypeId, JSEvents.mouseEvent, userData)) e.preventDefault();
  1778. };
  1779. var eventHandler = {
  1780. target: target,
  1781. allowsDeferredCalls: eventTypeString != 'mousemove' && eventTypeString != 'mouseenter' && eventTypeString != 'mouseleave', // Mouse move events do not allow fullscreen/pointer lock requests to be handled in them!
  1782. eventTypeString: eventTypeString,
  1783. callbackfunc: callbackfunc,
  1784. handlerFunc: mouseEventHandlerFunc,
  1785. useCapture: useCapture
  1786. };
  1787. JSEvents.registerOrRemoveHandler(eventHandler);
  1788. }
  1789. function _emscripten_set_click_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  1790. registerMouseEventCallback(target, userData, useCapture, callbackfunc, 4, "click", targetThread);
  1791. return 0;
  1792. }
  1793. function fillFullscreenChangeEventData(eventStruct) {
  1794. var fullscreenElement = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement;
  1795. var isFullscreen = !!fullscreenElement;
  1796. /** @suppress{checkTypes} */
  1797. HEAP32[((eventStruct)>>2)] = isFullscreen;
  1798. HEAP32[(((eventStruct)+(4))>>2)] = JSEvents.fullscreenEnabled();
  1799. // If transitioning to fullscreen, report info about the element that is now fullscreen.
  1800. // If transitioning to windowed mode, report info about the element that just was fullscreen.
  1801. var reportedElement = isFullscreen ? fullscreenElement : JSEvents.previousFullscreenElement;
  1802. var nodeName = JSEvents.getNodeNameForTarget(reportedElement);
  1803. var id = (reportedElement && reportedElement.id) ? reportedElement.id : '';
  1804. stringToUTF8(nodeName, eventStruct + 8, 128);
  1805. stringToUTF8(id, eventStruct + 136, 128);
  1806. HEAP32[(((eventStruct)+(264))>>2)] = reportedElement ? reportedElement.clientWidth : 0;
  1807. HEAP32[(((eventStruct)+(268))>>2)] = reportedElement ? reportedElement.clientHeight : 0;
  1808. HEAP32[(((eventStruct)+(272))>>2)] = screen.width;
  1809. HEAP32[(((eventStruct)+(276))>>2)] = screen.height;
  1810. if (isFullscreen) {
  1811. JSEvents.previousFullscreenElement = fullscreenElement;
  1812. }
  1813. }
  1814. function registerFullscreenChangeEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {
  1815. if (!JSEvents.fullscreenChangeEvent) JSEvents.fullscreenChangeEvent = _malloc( 280 );
  1816. var fullscreenChangeEventhandlerFunc = function(ev) {
  1817. var e = ev || event;
  1818. var fullscreenChangeEvent = JSEvents.fullscreenChangeEvent;
  1819. fillFullscreenChangeEventData(fullscreenChangeEvent);
  1820. if ((function(a1, a2, a3) { dynCall_iiii.apply(null, [callbackfunc, a1, a2, a3]); })(eventTypeId, fullscreenChangeEvent, userData)) e.preventDefault();
  1821. };
  1822. var eventHandler = {
  1823. target: target,
  1824. eventTypeString: eventTypeString,
  1825. callbackfunc: callbackfunc,
  1826. handlerFunc: fullscreenChangeEventhandlerFunc,
  1827. useCapture: useCapture
  1828. };
  1829. JSEvents.registerOrRemoveHandler(eventHandler);
  1830. }
  1831. function _emscripten_set_fullscreenchange_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  1832. if (!JSEvents.fullscreenEnabled()) return -1;
  1833. target = findEventTarget(target);
  1834. if (!target) return -4;
  1835. registerFullscreenChangeEventCallback(target, userData, useCapture, callbackfunc, 19, "fullscreenchange", targetThread);
  1836. // Unprefixed Fullscreen API shipped in Chromium 71 (https://bugs.chromium.org/p/chromium/issues/detail?id=383813)
  1837. // 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.
  1838. registerFullscreenChangeEventCallback(target, userData, useCapture, callbackfunc, 19, "webkitfullscreenchange", targetThread);
  1839. return 0;
  1840. }
  1841. function registerKeyEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {
  1842. if (!JSEvents.keyEvent) JSEvents.keyEvent = _malloc( 164 );
  1843. var keyEventHandlerFunc = function(e) {
  1844. var keyEventData = JSEvents.keyEvent;
  1845. var idx = keyEventData >> 2;
  1846. HEAP32[idx + 0] = e.location;
  1847. HEAP32[idx + 1] = e.ctrlKey;
  1848. HEAP32[idx + 2] = e.shiftKey;
  1849. HEAP32[idx + 3] = e.altKey;
  1850. HEAP32[idx + 4] = e.metaKey;
  1851. HEAP32[idx + 5] = e.repeat;
  1852. HEAP32[idx + 6] = e.charCode;
  1853. HEAP32[idx + 7] = e.keyCode;
  1854. HEAP32[idx + 8] = e.which;
  1855. stringToUTF8(e.key || '', keyEventData + 36, 32);
  1856. stringToUTF8(e.code || '', keyEventData + 68, 32);
  1857. stringToUTF8(e.char || '', keyEventData + 100, 32);
  1858. stringToUTF8(e.locale || '', keyEventData + 132, 32);
  1859. if ((function(a1, a2, a3) { dynCall_iiii.apply(null, [callbackfunc, a1, a2, a3]); })(eventTypeId, keyEventData, userData)) e.preventDefault();
  1860. };
  1861. var eventHandler = {
  1862. target: findEventTarget(target),
  1863. allowsDeferredCalls: true,
  1864. eventTypeString: eventTypeString,
  1865. callbackfunc: callbackfunc,
  1866. handlerFunc: keyEventHandlerFunc,
  1867. useCapture: useCapture
  1868. };
  1869. JSEvents.registerOrRemoveHandler(eventHandler);
  1870. }
  1871. function _emscripten_set_keydown_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  1872. registerKeyEventCallback(target, userData, useCapture, callbackfunc, 2, "keydown", targetThread);
  1873. return 0;
  1874. }
  1875. function _emscripten_set_keypress_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  1876. registerKeyEventCallback(target, userData, useCapture, callbackfunc, 1, "keypress", targetThread);
  1877. return 0;
  1878. }
  1879. function _emscripten_set_keyup_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  1880. registerKeyEventCallback(target, userData, useCapture, callbackfunc, 3, "keyup", targetThread);
  1881. return 0;
  1882. }
  1883. var Browser={mainLoop:{scheduler:null,method:"",currentlyRunningMainloop:0,func:null,arg:0,timingMode:0,timingValue:0,currentFrameNumber:0,queue:[],pause:function() {
  1884. Browser.mainLoop.scheduler = null;
  1885. // Incrementing this signals the previous main loop that it's now become old, and it must return.
  1886. Browser.mainLoop.currentlyRunningMainloop++;
  1887. },resume:function() {
  1888. Browser.mainLoop.currentlyRunningMainloop++;
  1889. var timingMode = Browser.mainLoop.timingMode;
  1890. var timingValue = Browser.mainLoop.timingValue;
  1891. var func = Browser.mainLoop.func;
  1892. Browser.mainLoop.func = null;
  1893. // do not set timing and call scheduler, we will do it on the next lines
  1894. setMainLoop(func, 0, false, Browser.mainLoop.arg, true);
  1895. _emscripten_set_main_loop_timing(timingMode, timingValue);
  1896. Browser.mainLoop.scheduler();
  1897. },updateStatus:function() {
  1898. if (Module['setStatus']) {
  1899. var message = Module['statusMessage'] || 'Please wait...';
  1900. var remaining = Browser.mainLoop.remainingBlockers;
  1901. var expected = Browser.mainLoop.expectedBlockers;
  1902. if (remaining) {
  1903. if (remaining < expected) {
  1904. Module['setStatus'](message + ' (' + (expected - remaining) + '/' + expected + ')');
  1905. } else {
  1906. Module['setStatus'](message);
  1907. }
  1908. } else {
  1909. Module['setStatus']('');
  1910. }
  1911. }
  1912. },runIter:function(func) {
  1913. if (ABORT) return;
  1914. if (Module['preMainLoop']) {
  1915. var preRet = Module['preMainLoop']();
  1916. if (preRet === false) {
  1917. return; // |return false| skips a frame
  1918. }
  1919. }
  1920. try {
  1921. func();
  1922. } catch (e) {
  1923. if (e instanceof ExitStatus) {
  1924. return;
  1925. } else if (e == 'unwind') {
  1926. return;
  1927. } else {
  1928. if (e && typeof e === 'object' && e.stack) err('exception thrown: ' + [e, e.stack]);
  1929. throw e;
  1930. }
  1931. }
  1932. if (Module['postMainLoop']) Module['postMainLoop']();
  1933. }},isFullscreen:false,pointerLock:false,moduleContextCreatedCallbacks:[],workers:[],init:function() {
  1934. if (!Module["preloadPlugins"]) Module["preloadPlugins"] = []; // needs to exist even in workers
  1935. if (Browser.initted) return;
  1936. Browser.initted = true;
  1937. try {
  1938. new Blob();
  1939. Browser.hasBlobConstructor = true;
  1940. } catch(e) {
  1941. Browser.hasBlobConstructor = false;
  1942. console.log("warning: no blob constructor, cannot create blobs with mimetypes");
  1943. }
  1944. Browser.BlobBuilder = typeof MozBlobBuilder != "undefined" ? MozBlobBuilder : (typeof WebKitBlobBuilder != "undefined" ? WebKitBlobBuilder : (!Browser.hasBlobConstructor ? console.log("warning: no BlobBuilder") : null));
  1945. Browser.URLObject = typeof window != "undefined" ? (window.URL ? window.URL : window.webkitURL) : undefined;
  1946. if (!Module.noImageDecoding && typeof Browser.URLObject === 'undefined') {
  1947. console.log("warning: Browser does not support creating object URLs. Built-in browser image decoding will not be available.");
  1948. Module.noImageDecoding = true;
  1949. }
  1950. // Support for plugins that can process preloaded files. You can add more of these to
  1951. // your app by creating and appending to Module.preloadPlugins.
  1952. //
  1953. // Each plugin is asked if it can handle a file based on the file's name. If it can,
  1954. // it is given the file's raw data. When it is done, it calls a callback with the file's
  1955. // (possibly modified) data. For example, a plugin might decompress a file, or it
  1956. // might create some side data structure for use later (like an Image element, etc.).
  1957. var imagePlugin = {};
  1958. imagePlugin['canHandle'] = function imagePlugin_canHandle(name) {
  1959. return !Module.noImageDecoding && /\.(jpg|jpeg|png|bmp)$/i.test(name);
  1960. };
  1961. imagePlugin['handle'] = function imagePlugin_handle(byteArray, name, onload, onerror) {
  1962. var b = null;
  1963. if (Browser.hasBlobConstructor) {
  1964. try {
  1965. b = new Blob([byteArray], { type: Browser.getMimetype(name) });
  1966. if (b.size !== byteArray.length) { // Safari bug #118630
  1967. // Safari's Blob can only take an ArrayBuffer
  1968. b = new Blob([(new Uint8Array(byteArray)).buffer], { type: Browser.getMimetype(name) });
  1969. }
  1970. } catch(e) {
  1971. warnOnce('Blob constructor present but fails: ' + e + '; falling back to blob builder');
  1972. }
  1973. }
  1974. if (!b) {
  1975. var bb = new Browser.BlobBuilder();
  1976. bb.append((new Uint8Array(byteArray)).buffer); // we need to pass a buffer, and must copy the array to get the right data range
  1977. b = bb.getBlob();
  1978. }
  1979. var url = Browser.URLObject.createObjectURL(b);
  1980. var img = new Image();
  1981. img.onload = function img_onload() {
  1982. assert(img.complete, 'Image ' + name + ' could not be decoded');
  1983. var canvas = document.createElement('canvas');
  1984. canvas.width = img.width;
  1985. canvas.height = img.height;
  1986. var ctx = canvas.getContext('2d');
  1987. ctx.drawImage(img, 0, 0);
  1988. Module["preloadedImages"][name] = canvas;
  1989. Browser.URLObject.revokeObjectURL(url);
  1990. if (onload) onload(byteArray);
  1991. };
  1992. img.onerror = function img_onerror(event) {
  1993. console.log('Image ' + url + ' could not be decoded');
  1994. if (onerror) onerror();
  1995. };
  1996. img.src = url;
  1997. };
  1998. Module['preloadPlugins'].push(imagePlugin);
  1999. var audioPlugin = {};
  2000. audioPlugin['canHandle'] = function audioPlugin_canHandle(name) {
  2001. return !Module.noAudioDecoding && name.substr(-4) in { '.ogg': 1, '.wav': 1, '.mp3': 1 };
  2002. };
  2003. audioPlugin['handle'] = function audioPlugin_handle(byteArray, name, onload, onerror) {
  2004. var done = false;
  2005. function finish(audio) {
  2006. if (done) return;
  2007. done = true;
  2008. Module["preloadedAudios"][name] = audio;
  2009. if (onload) onload(byteArray);
  2010. }
  2011. function fail() {
  2012. if (done) return;
  2013. done = true;
  2014. Module["preloadedAudios"][name] = new Audio(); // empty shim
  2015. if (onerror) onerror();
  2016. }
  2017. if (Browser.hasBlobConstructor) {
  2018. try {
  2019. var b = new Blob([byteArray], { type: Browser.getMimetype(name) });
  2020. } catch(e) {
  2021. return fail();
  2022. }
  2023. var url = Browser.URLObject.createObjectURL(b); // XXX we never revoke this!
  2024. var audio = new Audio();
  2025. audio.addEventListener('canplaythrough', function() { finish(audio) }, false); // use addEventListener due to chromium bug 124926
  2026. audio.onerror = function audio_onerror(event) {
  2027. if (done) return;
  2028. console.log('warning: browser could not fully decode audio ' + name + ', trying slower base64 approach');
  2029. function encode64(data) {
  2030. var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  2031. var PAD = '=';
  2032. var ret = '';
  2033. var leftchar = 0;
  2034. var leftbits = 0;
  2035. for (var i = 0; i < data.length; i++) {
  2036. leftchar = (leftchar << 8) | data[i];
  2037. leftbits += 8;
  2038. while (leftbits >= 6) {
  2039. var curr = (leftchar >> (leftbits-6)) & 0x3f;
  2040. leftbits -= 6;
  2041. ret += BASE[curr];
  2042. }
  2043. }
  2044. if (leftbits == 2) {
  2045. ret += BASE[(leftchar&3) << 4];
  2046. ret += PAD + PAD;
  2047. } else if (leftbits == 4) {
  2048. ret += BASE[(leftchar&0xf) << 2];
  2049. ret += PAD;
  2050. }
  2051. return ret;
  2052. }
  2053. audio.src = 'data:audio/x-' + name.substr(-3) + ';base64,' + encode64(byteArray);
  2054. finish(audio); // we don't wait for confirmation this worked - but it's worth trying
  2055. };
  2056. audio.src = url;
  2057. // workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror
  2058. Browser.safeSetTimeout(function() {
  2059. finish(audio); // try to use it even though it is not necessarily ready to play
  2060. }, 10000);
  2061. } else {
  2062. return fail();
  2063. }
  2064. };
  2065. Module['preloadPlugins'].push(audioPlugin);
  2066. // Canvas event setup
  2067. function pointerLockChange() {
  2068. Browser.pointerLock = document['pointerLockElement'] === Module['canvas'] ||
  2069. document['mozPointerLockElement'] === Module['canvas'] ||
  2070. document['webkitPointerLockElement'] === Module['canvas'] ||
  2071. document['msPointerLockElement'] === Module['canvas'];
  2072. }
  2073. var canvas = Module['canvas'];
  2074. if (canvas) {
  2075. // forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module
  2076. // Module['forcedAspectRatio'] = 4 / 3;
  2077. canvas.requestPointerLock = canvas['requestPointerLock'] ||
  2078. canvas['mozRequestPointerLock'] ||
  2079. canvas['webkitRequestPointerLock'] ||
  2080. canvas['msRequestPointerLock'] ||
  2081. function(){};
  2082. canvas.exitPointerLock = document['exitPointerLock'] ||
  2083. document['mozExitPointerLock'] ||
  2084. document['webkitExitPointerLock'] ||
  2085. document['msExitPointerLock'] ||
  2086. function(){}; // no-op if function does not exist
  2087. canvas.exitPointerLock = canvas.exitPointerLock.bind(document);
  2088. document.addEventListener('pointerlockchange', pointerLockChange, false);
  2089. document.addEventListener('mozpointerlockchange', pointerLockChange, false);
  2090. document.addEventListener('webkitpointerlockchange', pointerLockChange, false);
  2091. document.addEventListener('mspointerlockchange', pointerLockChange, false);
  2092. if (Module['elementPointerLock']) {
  2093. canvas.addEventListener("click", function(ev) {
  2094. if (!Browser.pointerLock && Module['canvas'].requestPointerLock) {
  2095. Module['canvas'].requestPointerLock();
  2096. ev.preventDefault();
  2097. }
  2098. }, false);
  2099. }
  2100. }
  2101. },createContext:function(canvas, useWebGL, setInModule, webGLContextAttributes) {
  2102. 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.
  2103. var ctx;
  2104. var contextHandle;
  2105. if (useWebGL) {
  2106. // For GLES2/desktop GL compatibility, adjust a few defaults to be different to WebGL defaults, so that they align better with the desktop defaults.
  2107. var contextAttributes = {
  2108. antialias: false,
  2109. alpha: false,
  2110. majorVersion: (typeof WebGL2RenderingContext !== 'undefined') ? 2 : 1,
  2111. };
  2112. if (webGLContextAttributes) {
  2113. for (var attribute in webGLContextAttributes) {
  2114. contextAttributes[attribute] = webGLContextAttributes[attribute];
  2115. }
  2116. }
  2117. // 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
  2118. // actually compiled in because application is not doing any GL operations. TODO: Ideally if GL is not being used, this function
  2119. // Browser.createContext() should not even be emitted.
  2120. if (typeof GL !== 'undefined') {
  2121. contextHandle = GL.createContext(canvas, contextAttributes);
  2122. if (contextHandle) {
  2123. ctx = GL.getContext(contextHandle).GLctx;
  2124. }
  2125. }
  2126. } else {
  2127. ctx = canvas.getContext('2d');
  2128. }
  2129. if (!ctx) return null;
  2130. if (setInModule) {
  2131. 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');
  2132. Module.ctx = ctx;
  2133. if (useWebGL) GL.makeContextCurrent(contextHandle);
  2134. Module.useWebGL = useWebGL;
  2135. Browser.moduleContextCreatedCallbacks.forEach(function(callback) { callback() });
  2136. Browser.init();
  2137. }
  2138. return ctx;
  2139. },destroyContext:function(canvas, useWebGL, setInModule) {},fullscreenHandlersInstalled:false,lockPointer:undefined,resizeCanvas:undefined,requestFullscreen:function(lockPointer, resizeCanvas) {
  2140. Browser.lockPointer = lockPointer;
  2141. Browser.resizeCanvas = resizeCanvas;
  2142. if (typeof Browser.lockPointer === 'undefined') Browser.lockPointer = true;
  2143. if (typeof Browser.resizeCanvas === 'undefined') Browser.resizeCanvas = false;
  2144. var canvas = Module['canvas'];
  2145. function fullscreenChange() {
  2146. Browser.isFullscreen = false;
  2147. var canvasContainer = canvas.parentNode;
  2148. if ((document['fullscreenElement'] || document['mozFullScreenElement'] ||
  2149. document['msFullscreenElement'] || document['webkitFullscreenElement'] ||
  2150. document['webkitCurrentFullScreenElement']) === canvasContainer) {
  2151. canvas.exitFullscreen = Browser.exitFullscreen;
  2152. if (Browser.lockPointer) canvas.requestPointerLock();
  2153. Browser.isFullscreen = true;
  2154. if (Browser.resizeCanvas) {
  2155. Browser.setFullscreenCanvasSize();
  2156. } else {
  2157. Browser.updateCanvasDimensions(canvas);
  2158. }
  2159. } else {
  2160. // remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen
  2161. canvasContainer.parentNode.insertBefore(canvas, canvasContainer);
  2162. canvasContainer.parentNode.removeChild(canvasContainer);
  2163. if (Browser.resizeCanvas) {
  2164. Browser.setWindowedCanvasSize();
  2165. } else {
  2166. Browser.updateCanvasDimensions(canvas);
  2167. }
  2168. }
  2169. if (Module['onFullScreen']) Module['onFullScreen'](Browser.isFullscreen);
  2170. if (Module['onFullscreen']) Module['onFullscreen'](Browser.isFullscreen);
  2171. }
  2172. if (!Browser.fullscreenHandlersInstalled) {
  2173. Browser.fullscreenHandlersInstalled = true;
  2174. document.addEventListener('fullscreenchange', fullscreenChange, false);
  2175. document.addEventListener('mozfullscreenchange', fullscreenChange, false);
  2176. document.addEventListener('webkitfullscreenchange', fullscreenChange, false);
  2177. document.addEventListener('MSFullscreenChange', fullscreenChange, false);
  2178. }
  2179. // 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
  2180. var canvasContainer = document.createElement("div");
  2181. canvas.parentNode.insertBefore(canvasContainer, canvas);
  2182. canvasContainer.appendChild(canvas);
  2183. // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size)
  2184. canvasContainer.requestFullscreen = canvasContainer['requestFullscreen'] ||
  2185. canvasContainer['mozRequestFullScreen'] ||
  2186. canvasContainer['msRequestFullscreen'] ||
  2187. (canvasContainer['webkitRequestFullscreen'] ? function() { canvasContainer['webkitRequestFullscreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null) ||
  2188. (canvasContainer['webkitRequestFullScreen'] ? function() { canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null);
  2189. canvasContainer.requestFullscreen();
  2190. },exitFullscreen:function() {
  2191. // This is workaround for chrome. Trying to exit from fullscreen
  2192. // not in fullscreen state will cause "TypeError: Document not active"
  2193. // in chrome. See https://github.com/emscripten-core/emscripten/pull/8236
  2194. if (!Browser.isFullscreen) {
  2195. return false;
  2196. }
  2197. var CFS = document['exitFullscreen'] ||
  2198. document['cancelFullScreen'] ||
  2199. document['mozCancelFullScreen'] ||
  2200. document['msExitFullscreen'] ||
  2201. document['webkitCancelFullScreen'] ||
  2202. (function() {});
  2203. CFS.apply(document, []);
  2204. return true;
  2205. },nextRAF:0,fakeRequestAnimationFrame:function(func) {
  2206. // try to keep 60fps between calls to here
  2207. var now = Date.now();
  2208. if (Browser.nextRAF === 0) {
  2209. Browser.nextRAF = now + 1000/60;
  2210. } else {
  2211. while (now + 2 >= Browser.nextRAF) { // fudge a little, to avoid timer jitter causing us to do lots of delay:0
  2212. Browser.nextRAF += 1000/60;
  2213. }
  2214. }
  2215. var delay = Math.max(Browser.nextRAF - now, 0);
  2216. setTimeout(func, delay);
  2217. },requestAnimationFrame:function(func) {
  2218. if (typeof requestAnimationFrame === 'function') {
  2219. requestAnimationFrame(func);
  2220. return;
  2221. }
  2222. var RAF = Browser.fakeRequestAnimationFrame;
  2223. RAF(func);
  2224. },safeRequestAnimationFrame:function(func) {
  2225. return Browser.requestAnimationFrame(function() {
  2226. if (ABORT) return;
  2227. func();
  2228. });
  2229. },safeSetTimeout:function(func, timeout) {
  2230. noExitRuntime = true;
  2231. return setTimeout(function() {
  2232. if (ABORT) return;
  2233. func();
  2234. }, timeout);
  2235. },getMimetype:function(name) {
  2236. return {
  2237. 'jpg': 'image/jpeg',
  2238. 'jpeg': 'image/jpeg',
  2239. 'png': 'image/png',
  2240. 'bmp': 'image/bmp',
  2241. 'ogg': 'audio/ogg',
  2242. 'wav': 'audio/wav',
  2243. 'mp3': 'audio/mpeg'
  2244. }[name.substr(name.lastIndexOf('.')+1)];
  2245. },getUserMedia:function(func) {
  2246. if(!window.getUserMedia) {
  2247. window.getUserMedia = navigator['getUserMedia'] ||
  2248. navigator['mozGetUserMedia'];
  2249. }
  2250. window.getUserMedia(func);
  2251. },getMovementX:function(event) {
  2252. return event['movementX'] ||
  2253. event['mozMovementX'] ||
  2254. event['webkitMovementX'] ||
  2255. 0;
  2256. },getMovementY:function(event) {
  2257. return event['movementY'] ||
  2258. event['mozMovementY'] ||
  2259. event['webkitMovementY'] ||
  2260. 0;
  2261. },getMouseWheelDelta:function(event) {
  2262. var delta = 0;
  2263. switch (event.type) {
  2264. case 'DOMMouseScroll':
  2265. // 3 lines make up a step
  2266. delta = event.detail / 3;
  2267. break;
  2268. case 'mousewheel':
  2269. // 120 units make up a step
  2270. delta = event.wheelDelta / 120;
  2271. break;
  2272. case 'wheel':
  2273. delta = event.deltaY
  2274. switch(event.deltaMode) {
  2275. case 0:
  2276. // DOM_DELTA_PIXEL: 100 pixels make up a step
  2277. delta /= 100;
  2278. break;
  2279. case 1:
  2280. // DOM_DELTA_LINE: 3 lines make up a step
  2281. delta /= 3;
  2282. break;
  2283. case 2:
  2284. // DOM_DELTA_PAGE: A page makes up 80 steps
  2285. delta *= 80;
  2286. break;
  2287. default:
  2288. throw 'unrecognized mouse wheel delta mode: ' + event.deltaMode;
  2289. }
  2290. break;
  2291. default:
  2292. throw 'unrecognized mouse wheel event: ' + event.type;
  2293. }
  2294. return delta;
  2295. },mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,touches:{},lastTouches:{},calculateMouseEvent:function(event) { // event should be mousemove, mousedown or mouseup
  2296. if (Browser.pointerLock) {
  2297. // When the pointer is locked, calculate the coordinates
  2298. // based on the movement of the mouse.
  2299. // Workaround for Firefox bug 764498
  2300. if (event.type != 'mousemove' &&
  2301. ('mozMovementX' in event)) {
  2302. Browser.mouseMovementX = Browser.mouseMovementY = 0;
  2303. } else {
  2304. Browser.mouseMovementX = Browser.getMovementX(event);
  2305. Browser.mouseMovementY = Browser.getMovementY(event);
  2306. }
  2307. // check if SDL is available
  2308. if (typeof SDL != "undefined") {
  2309. Browser.mouseX = SDL.mouseX + Browser.mouseMovementX;
  2310. Browser.mouseY = SDL.mouseY + Browser.mouseMovementY;
  2311. } else {
  2312. // just add the mouse delta to the current absolut mouse position
  2313. // FIXME: ideally this should be clamped against the canvas size and zero
  2314. Browser.mouseX += Browser.mouseMovementX;
  2315. Browser.mouseY += Browser.mouseMovementY;
  2316. }
  2317. } else {
  2318. // Otherwise, calculate the movement based on the changes
  2319. // in the coordinates.
  2320. var rect = Module["canvas"].getBoundingClientRect();
  2321. var cw = Module["canvas"].width;
  2322. var ch = Module["canvas"].height;
  2323. // Neither .scrollX or .pageXOffset are defined in a spec, but
  2324. // we prefer .scrollX because it is currently in a spec draft.
  2325. // (see: http://www.w3.org/TR/2013/WD-cssom-view-20131217/)
  2326. var scrollX = ((typeof window.scrollX !== 'undefined') ? window.scrollX : window.pageXOffset);
  2327. var scrollY = ((typeof window.scrollY !== 'undefined') ? window.scrollY : window.pageYOffset);
  2328. if (event.type === 'touchstart' || event.type === 'touchend' || event.type === 'touchmove') {
  2329. var touch = event.touch;
  2330. if (touch === undefined) {
  2331. return; // the "touch" property is only defined in SDL
  2332. }
  2333. var adjustedX = touch.pageX - (scrollX + rect.left);
  2334. var adjustedY = touch.pageY - (scrollY + rect.top);
  2335. adjustedX = adjustedX * (cw / rect.width);
  2336. adjustedY = adjustedY * (ch / rect.height);
  2337. var coords = { x: adjustedX, y: adjustedY };
  2338. if (event.type === 'touchstart') {
  2339. Browser.lastTouches[touch.identifier] = coords;
  2340. Browser.touches[touch.identifier] = coords;
  2341. } else if (event.type === 'touchend' || event.type === 'touchmove') {
  2342. var last = Browser.touches[touch.identifier];
  2343. if (!last) last = coords;
  2344. Browser.lastTouches[touch.identifier] = last;
  2345. Browser.touches[touch.identifier] = coords;
  2346. }
  2347. return;
  2348. }
  2349. var x = event.pageX - (scrollX + rect.left);
  2350. var y = event.pageY - (scrollY + rect.top);
  2351. // the canvas might be CSS-scaled compared to its backbuffer;
  2352. // SDL-using content will want mouse coordinates in terms
  2353. // of backbuffer units.
  2354. x = x * (cw / rect.width);
  2355. y = y * (ch / rect.height);
  2356. Browser.mouseMovementX = x - Browser.mouseX;
  2357. Browser.mouseMovementY = y - Browser.mouseY;
  2358. Browser.mouseX = x;
  2359. Browser.mouseY = y;
  2360. }
  2361. },asyncLoad:function(url, onload, onerror, noRunDep) {
  2362. var dep = !noRunDep ? getUniqueRunDependency('al ' + url) : '';
  2363. readAsync(url, function(arrayBuffer) {
  2364. assert(arrayBuffer, 'Loading data file "' + url + '" failed (no arrayBuffer).');
  2365. onload(new Uint8Array(arrayBuffer));
  2366. if (dep) removeRunDependency(dep);
  2367. }, function(event) {
  2368. if (onerror) {
  2369. onerror();
  2370. } else {
  2371. throw 'Loading data file "' + url + '" failed.';
  2372. }
  2373. });
  2374. if (dep) addRunDependency(dep);
  2375. },resizeListeners:[],updateResizeListeners:function() {
  2376. var canvas = Module['canvas'];
  2377. Browser.resizeListeners.forEach(function(listener) {
  2378. listener(canvas.width, canvas.height);
  2379. });
  2380. },setCanvasSize:function(width, height, noUpdates) {
  2381. var canvas = Module['canvas'];
  2382. Browser.updateCanvasDimensions(canvas, width, height);
  2383. if (!noUpdates) Browser.updateResizeListeners();
  2384. },windowedWidth:0,windowedHeight:0,setFullscreenCanvasSize:function() {
  2385. // check if SDL is available
  2386. if (typeof SDL != "undefined") {
  2387. var flags = HEAPU32[((SDL.screen)>>2)];
  2388. flags = flags | 0x00800000; // set SDL_FULLSCREEN flag
  2389. HEAP32[((SDL.screen)>>2)] = flags
  2390. }
  2391. Browser.updateCanvasDimensions(Module['canvas']);
  2392. Browser.updateResizeListeners();
  2393. },setWindowedCanvasSize:function() {
  2394. // check if SDL is available
  2395. if (typeof SDL != "undefined") {
  2396. var flags = HEAPU32[((SDL.screen)>>2)];
  2397. flags = flags & ~0x00800000; // clear SDL_FULLSCREEN flag
  2398. HEAP32[((SDL.screen)>>2)] = flags
  2399. }
  2400. Browser.updateCanvasDimensions(Module['canvas']);
  2401. Browser.updateResizeListeners();
  2402. },updateCanvasDimensions:function(canvas, wNative, hNative) {
  2403. if (wNative && hNative) {
  2404. canvas.widthNative = wNative;
  2405. canvas.heightNative = hNative;
  2406. } else {
  2407. wNative = canvas.widthNative;
  2408. hNative = canvas.heightNative;
  2409. }
  2410. var w = wNative;
  2411. var h = hNative;
  2412. if (Module['forcedAspectRatio'] && Module['forcedAspectRatio'] > 0) {
  2413. if (w/h < Module['forcedAspectRatio']) {
  2414. w = Math.round(h * Module['forcedAspectRatio']);
  2415. } else {
  2416. h = Math.round(w / Module['forcedAspectRatio']);
  2417. }
  2418. }
  2419. if (((document['fullscreenElement'] || document['mozFullScreenElement'] ||
  2420. document['msFullscreenElement'] || document['webkitFullscreenElement'] ||
  2421. document['webkitCurrentFullScreenElement']) === canvas.parentNode) && (typeof screen != 'undefined')) {
  2422. var factor = Math.min(screen.width / w, screen.height / h);
  2423. w = Math.round(w * factor);
  2424. h = Math.round(h * factor);
  2425. }
  2426. if (Browser.resizeCanvas) {
  2427. if (canvas.width != w) canvas.width = w;
  2428. if (canvas.height != h) canvas.height = h;
  2429. if (typeof canvas.style != 'undefined') {
  2430. canvas.style.removeProperty( "width");
  2431. canvas.style.removeProperty("height");
  2432. }
  2433. } else {
  2434. if (canvas.width != wNative) canvas.width = wNative;
  2435. if (canvas.height != hNative) canvas.height = hNative;
  2436. if (typeof canvas.style != 'undefined') {
  2437. if (w != wNative || h != hNative) {
  2438. canvas.style.setProperty( "width", w + "px", "important");
  2439. canvas.style.setProperty("height", h + "px", "important");
  2440. } else {
  2441. canvas.style.removeProperty( "width");
  2442. canvas.style.removeProperty("height");
  2443. }
  2444. }
  2445. }
  2446. },wgetRequests:{},nextWgetRequestHandle:0,getNextWgetRequestHandle:function() {
  2447. var handle = Browser.nextWgetRequestHandle;
  2448. Browser.nextWgetRequestHandle++;
  2449. return handle;
  2450. }};
  2451. function _emscripten_set_main_loop_timing(mode, value) {
  2452. Browser.mainLoop.timingMode = mode;
  2453. Browser.mainLoop.timingValue = value;
  2454. if (!Browser.mainLoop.func) {
  2455. return 1; // Return non-zero on failure, can't set timing mode when there is no main loop.
  2456. }
  2457. if (mode == 0 /*EM_TIMING_SETTIMEOUT*/) {
  2458. Browser.mainLoop.scheduler = function Browser_mainLoop_scheduler_setTimeout() {
  2459. var timeUntilNextTick = Math.max(0, Browser.mainLoop.tickStartTime + value - _emscripten_get_now())|0;
  2460. setTimeout(Browser.mainLoop.runner, timeUntilNextTick); // doing this each time means that on exception, we stop
  2461. };
  2462. Browser.mainLoop.method = 'timeout';
  2463. } else if (mode == 1 /*EM_TIMING_RAF*/) {
  2464. Browser.mainLoop.scheduler = function Browser_mainLoop_scheduler_rAF() {
  2465. Browser.requestAnimationFrame(Browser.mainLoop.runner);
  2466. };
  2467. Browser.mainLoop.method = 'rAF';
  2468. } else if (mode == 2 /*EM_TIMING_SETIMMEDIATE*/) {
  2469. if (typeof setImmediate === 'undefined') {
  2470. // Emulate setImmediate. (note: not a complete polyfill, we don't emulate clearImmediate() to keep code size to minimum, since not needed)
  2471. var setImmediates = [];
  2472. var emscriptenMainLoopMessageId = 'setimmediate';
  2473. var Browser_setImmediate_messageHandler = function(event) {
  2474. // 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,
  2475. // so check for both cases.
  2476. if (event.data === emscriptenMainLoopMessageId || event.data.target === emscriptenMainLoopMessageId) {
  2477. event.stopPropagation();
  2478. setImmediates.shift()();
  2479. }
  2480. }
  2481. addEventListener("message", Browser_setImmediate_messageHandler, true);
  2482. setImmediate = /** @type{function(function(): ?, ...?): number} */(function Browser_emulated_setImmediate(func) {
  2483. setImmediates.push(func);
  2484. if (ENVIRONMENT_IS_WORKER) {
  2485. if (Module['setImmediates'] === undefined) Module['setImmediates'] = [];
  2486. Module['setImmediates'].push(func);
  2487. postMessage({target: emscriptenMainLoopMessageId}); // In --proxy-to-worker, route the message via proxyClient.js
  2488. } else postMessage(emscriptenMainLoopMessageId, "*"); // On the main thread, can just send the message to itself.
  2489. })
  2490. }
  2491. Browser.mainLoop.scheduler = function Browser_mainLoop_scheduler_setImmediate() {
  2492. setImmediate(Browser.mainLoop.runner);
  2493. };
  2494. Browser.mainLoop.method = 'immediate';
  2495. }
  2496. return 0;
  2497. }
  2498. var _emscripten_get_now;if (ENVIRONMENT_IS_NODE) {
  2499. _emscripten_get_now = function() {
  2500. var t = process['hrtime']();
  2501. return t[0] * 1e3 + t[1] / 1e6;
  2502. };
  2503. } else if (typeof dateNow !== 'undefined') {
  2504. _emscripten_get_now = dateNow;
  2505. } else _emscripten_get_now = function() { return performance.now(); }
  2506. ;
  2507. function setMainLoop(browserIterationFunc, fps, simulateInfiniteLoop, arg, noSetTiming) {
  2508. noExitRuntime = true;
  2509. 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.');
  2510. Browser.mainLoop.func = browserIterationFunc;
  2511. Browser.mainLoop.arg = arg;
  2512. var thisMainLoopId = Browser.mainLoop.currentlyRunningMainloop;
  2513. Browser.mainLoop.runner = function Browser_mainLoop_runner() {
  2514. if (ABORT) return;
  2515. if (Browser.mainLoop.queue.length > 0) {
  2516. var start = Date.now();
  2517. var blocker = Browser.mainLoop.queue.shift();
  2518. blocker.func(blocker.arg);
  2519. if (Browser.mainLoop.remainingBlockers) {
  2520. var remaining = Browser.mainLoop.remainingBlockers;
  2521. var next = remaining%1 == 0 ? remaining-1 : Math.floor(remaining);
  2522. if (blocker.counted) {
  2523. Browser.mainLoop.remainingBlockers = next;
  2524. } else {
  2525. // not counted, but move the progress along a tiny bit
  2526. next = next + 0.5; // do not steal all the next one's progress
  2527. Browser.mainLoop.remainingBlockers = (8*remaining + next)/9;
  2528. }
  2529. }
  2530. console.log('main loop blocker "' + blocker.name + '" took ' + (Date.now() - start) + ' ms'); //, left: ' + Browser.mainLoop.remainingBlockers);
  2531. Browser.mainLoop.updateStatus();
  2532. // catches pause/resume main loop from blocker execution
  2533. if (thisMainLoopId < Browser.mainLoop.currentlyRunningMainloop) return;
  2534. setTimeout(Browser.mainLoop.runner, 0);
  2535. return;
  2536. }
  2537. // catch pauses from non-main loop sources
  2538. if (thisMainLoopId < Browser.mainLoop.currentlyRunningMainloop) return;
  2539. // Implement very basic swap interval control
  2540. Browser.mainLoop.currentFrameNumber = Browser.mainLoop.currentFrameNumber + 1 | 0;
  2541. if (Browser.mainLoop.timingMode == 1/*EM_TIMING_RAF*/ && Browser.mainLoop.timingValue > 1 && Browser.mainLoop.currentFrameNumber % Browser.mainLoop.timingValue != 0) {
  2542. // Not the scheduled time to render this frame - skip.
  2543. Browser.mainLoop.scheduler();
  2544. return;
  2545. } else if (Browser.mainLoop.timingMode == 0/*EM_TIMING_SETTIMEOUT*/) {
  2546. Browser.mainLoop.tickStartTime = _emscripten_get_now();
  2547. }
  2548. // Signal GL rendering layer that processing of a new frame is about to start. This helps it optimize
  2549. // VBO double-buffering and reduce GPU stalls.
  2550. Browser.mainLoop.runIter(browserIterationFunc);
  2551. // catch pauses from the main loop itself
  2552. if (thisMainLoopId < Browser.mainLoop.currentlyRunningMainloop) return;
  2553. // Queue new audio data. This is important to be right after the main loop invocation, so that we will immediately be able
  2554. // to queue the newest produced audio samples.
  2555. // TODO: Consider adding pre- and post- rAF callbacks so that GL.newRenderingFrameStarted() and SDL.audio.queueNewAudioData()
  2556. // do not need to be hardcoded into this function, but can be more generic.
  2557. if (typeof SDL === 'object' && SDL.audio && SDL.audio.queueNewAudioData) SDL.audio.queueNewAudioData();
  2558. Browser.mainLoop.scheduler();
  2559. }
  2560. if (!noSetTiming) {
  2561. if (fps && fps > 0) _emscripten_set_main_loop_timing(0/*EM_TIMING_SETTIMEOUT*/, 1000.0 / fps);
  2562. else _emscripten_set_main_loop_timing(1/*EM_TIMING_RAF*/, 1); // Do rAF by rendering each frame (no decimating)
  2563. Browser.mainLoop.scheduler();
  2564. }
  2565. if (simulateInfiniteLoop) {
  2566. throw 'unwind';
  2567. }
  2568. }
  2569. function _emscripten_set_main_loop(func, fps, simulateInfiniteLoop) {
  2570. var browserIterationFunc = (function() { dynCall_v.call(null, func); });
  2571. setMainLoop(browserIterationFunc, fps, simulateInfiniteLoop);
  2572. }
  2573. function _emscripten_set_mousedown_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  2574. registerMouseEventCallback(target, userData, useCapture, callbackfunc, 5, "mousedown", targetThread);
  2575. return 0;
  2576. }
  2577. function _emscripten_set_mouseenter_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  2578. registerMouseEventCallback(target, userData, useCapture, callbackfunc, 33, "mouseenter", targetThread);
  2579. return 0;
  2580. }
  2581. function _emscripten_set_mouseleave_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  2582. registerMouseEventCallback(target, userData, useCapture, callbackfunc, 34, "mouseleave", targetThread);
  2583. return 0;
  2584. }
  2585. function _emscripten_set_mousemove_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  2586. registerMouseEventCallback(target, userData, useCapture, callbackfunc, 8, "mousemove", targetThread);
  2587. return 0;
  2588. }
  2589. function _emscripten_set_mouseup_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  2590. registerMouseEventCallback(target, userData, useCapture, callbackfunc, 6, "mouseup", targetThread);
  2591. return 0;
  2592. }
  2593. function registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {
  2594. if (!JSEvents.pointerlockChangeEvent) JSEvents.pointerlockChangeEvent = _malloc( 260 );
  2595. var pointerlockChangeEventHandlerFunc = function(ev) {
  2596. var e = ev || event;
  2597. var pointerlockChangeEvent = JSEvents.pointerlockChangeEvent;
  2598. fillPointerlockChangeEventData(pointerlockChangeEvent);
  2599. if ((function(a1, a2, a3) { dynCall_iiii.apply(null, [callbackfunc, a1, a2, a3]); })(eventTypeId, pointerlockChangeEvent, userData)) e.preventDefault();
  2600. };
  2601. var eventHandler = {
  2602. target: target,
  2603. eventTypeString: eventTypeString,
  2604. callbackfunc: callbackfunc,
  2605. handlerFunc: pointerlockChangeEventHandlerFunc,
  2606. useCapture: useCapture
  2607. };
  2608. JSEvents.registerOrRemoveHandler(eventHandler);
  2609. }
  2610. /** @suppress {missingProperties} */
  2611. function _emscripten_set_pointerlockchange_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  2612. // TODO: Currently not supported in pthreads or in --proxy-to-worker mode. (In pthreads mode, document object is not defined)
  2613. if (!document || !document.body || (!document.body.requestPointerLock && !document.body.mozRequestPointerLock && !document.body.webkitRequestPointerLock && !document.body.msRequestPointerLock)) {
  2614. return -1;
  2615. }
  2616. target = findEventTarget(target);
  2617. if (!target) return -4;
  2618. registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "pointerlockchange", targetThread);
  2619. registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "mozpointerlockchange", targetThread);
  2620. registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "webkitpointerlockchange", targetThread);
  2621. registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "mspointerlockchange", targetThread);
  2622. return 0;
  2623. }
  2624. function registerUiEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {
  2625. if (!JSEvents.uiEvent) JSEvents.uiEvent = _malloc( 36 );
  2626. target = findEventTarget(target);
  2627. var uiEventHandlerFunc = function(ev) {
  2628. var e = ev || event;
  2629. if (e.target != target) {
  2630. // Never take ui events such as scroll via a 'bubbled' route, but always from the direct element that
  2631. // was targeted. Otherwise e.g. if app logs a message in response to a page scroll, the Emscripten log
  2632. // message box could cause to scroll, generating a new (bubbled) scroll message, causing a new log print,
  2633. // causing a new scroll, etc..
  2634. return;
  2635. }
  2636. var b = document.body; // Take document.body to a variable, Closure compiler does not outline access to it on its own.
  2637. if (!b) {
  2638. // During a page unload 'body' can be null, with "Cannot read property 'clientWidth' of null" being thrown
  2639. return;
  2640. }
  2641. var uiEvent = JSEvents.uiEvent;
  2642. HEAP32[((uiEvent)>>2)] = e.detail;
  2643. HEAP32[(((uiEvent)+(4))>>2)] = b.clientWidth;
  2644. HEAP32[(((uiEvent)+(8))>>2)] = b.clientHeight;
  2645. HEAP32[(((uiEvent)+(12))>>2)] = innerWidth;
  2646. HEAP32[(((uiEvent)+(16))>>2)] = innerHeight;
  2647. HEAP32[(((uiEvent)+(20))>>2)] = outerWidth;
  2648. HEAP32[(((uiEvent)+(24))>>2)] = outerHeight;
  2649. HEAP32[(((uiEvent)+(28))>>2)] = pageXOffset;
  2650. HEAP32[(((uiEvent)+(32))>>2)] = pageYOffset;
  2651. if ((function(a1, a2, a3) { dynCall_iiii.apply(null, [callbackfunc, a1, a2, a3]); })(eventTypeId, uiEvent, userData)) e.preventDefault();
  2652. };
  2653. var eventHandler = {
  2654. target: target,
  2655. eventTypeString: eventTypeString,
  2656. callbackfunc: callbackfunc,
  2657. handlerFunc: uiEventHandlerFunc,
  2658. useCapture: useCapture
  2659. };
  2660. JSEvents.registerOrRemoveHandler(eventHandler);
  2661. }
  2662. function _emscripten_set_resize_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  2663. registerUiEventCallback(target, userData, useCapture, callbackfunc, 10, "resize", targetThread);
  2664. return 0;
  2665. }
  2666. function registerWheelEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {
  2667. if (!JSEvents.wheelEvent) JSEvents.wheelEvent = _malloc( 96 );
  2668. // The DOM Level 3 events spec event 'wheel'
  2669. var wheelHandlerFunc = function(ev) {
  2670. var e = ev || event;
  2671. var wheelEvent = JSEvents.wheelEvent;
  2672. fillMouseEventData(wheelEvent, e, target);
  2673. HEAPF64[(((wheelEvent)+(64))>>3)] = e["deltaX"];
  2674. HEAPF64[(((wheelEvent)+(72))>>3)] = e["deltaY"];
  2675. HEAPF64[(((wheelEvent)+(80))>>3)] = e["deltaZ"];
  2676. HEAP32[(((wheelEvent)+(88))>>2)] = e["deltaMode"];
  2677. if ((function(a1, a2, a3) { dynCall_iiii.apply(null, [callbackfunc, a1, a2, a3]); })(eventTypeId, wheelEvent, userData)) e.preventDefault();
  2678. };
  2679. var eventHandler = {
  2680. target: target,
  2681. allowsDeferredCalls: true,
  2682. eventTypeString: eventTypeString,
  2683. callbackfunc: callbackfunc,
  2684. handlerFunc: wheelHandlerFunc,
  2685. useCapture: useCapture
  2686. };
  2687. JSEvents.registerOrRemoveHandler(eventHandler);
  2688. }
  2689. function _emscripten_set_wheel_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
  2690. target = findEventTarget(target);
  2691. if (typeof target.onwheel !== 'undefined') {
  2692. registerWheelEventCallback(target, userData, useCapture, callbackfunc, 9, "wheel", targetThread);
  2693. return 0;
  2694. } else {
  2695. return -1;
  2696. }
  2697. }
  2698. function _emscripten_sleep(ms) {
  2699. Asyncify.handleSleep(function(wakeUp) {
  2700. Browser.safeSetTimeout(wakeUp, ms);
  2701. });
  2702. }
  2703. function __webgl_enable_ANGLE_instanced_arrays(ctx) {
  2704. // Extension available in WebGL 1 from Firefox 26 and Google Chrome 30 onwards. Core feature in WebGL 2.
  2705. var ext = ctx.getExtension('ANGLE_instanced_arrays');
  2706. if (ext) {
  2707. ctx['vertexAttribDivisor'] = function(index, divisor) { ext['vertexAttribDivisorANGLE'](index, divisor); };
  2708. ctx['drawArraysInstanced'] = function(mode, first, count, primcount) { ext['drawArraysInstancedANGLE'](mode, first, count, primcount); };
  2709. ctx['drawElementsInstanced'] = function(mode, count, type, indices, primcount) { ext['drawElementsInstancedANGLE'](mode, count, type, indices, primcount); };
  2710. return 1;
  2711. }
  2712. }
  2713. function __webgl_enable_OES_vertex_array_object(ctx) {
  2714. // Extension available in WebGL 1 from Firefox 25 and WebKit 536.28/desktop Safari 6.0.3 onwards. Core feature in WebGL 2.
  2715. var ext = ctx.getExtension('OES_vertex_array_object');
  2716. if (ext) {
  2717. ctx['createVertexArray'] = function() { return ext['createVertexArrayOES'](); };
  2718. ctx['deleteVertexArray'] = function(vao) { ext['deleteVertexArrayOES'](vao); };
  2719. ctx['bindVertexArray'] = function(vao) { ext['bindVertexArrayOES'](vao); };
  2720. ctx['isVertexArray'] = function(vao) { return ext['isVertexArrayOES'](vao); };
  2721. return 1;
  2722. }
  2723. }
  2724. function __webgl_enable_WEBGL_draw_buffers(ctx) {
  2725. // Extension available in WebGL 1 from Firefox 28 onwards. Core feature in WebGL 2.
  2726. var ext = ctx.getExtension('WEBGL_draw_buffers');
  2727. if (ext) {
  2728. ctx['drawBuffers'] = function(n, bufs) { ext['drawBuffersWEBGL'](n, bufs); };
  2729. return 1;
  2730. }
  2731. }
  2732. function __webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance(ctx) {
  2733. // Closure is expected to be allowed to minify the '.dibvbi' property, so not accessing it quoted.
  2734. return !!(ctx.dibvbi = ctx.getExtension('WEBGL_draw_instanced_base_vertex_base_instance'));
  2735. }
  2736. function __webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance(ctx) {
  2737. // Closure is expected to be allowed to minify the '.mdibvbi' property, so not accessing it quoted.
  2738. return !!(ctx.mdibvbi = ctx.getExtension('WEBGL_multi_draw_instanced_base_vertex_base_instance'));
  2739. }
  2740. function __webgl_enable_WEBGL_multi_draw(ctx) {
  2741. // Closure is expected to be allowed to minify the '.multiDrawWebgl' property, so not accessing it quoted.
  2742. return !!(ctx.multiDrawWebgl = ctx.getExtension('WEBGL_multi_draw'));
  2743. }
  2744. var GL={counter:1,buffers:[],programs:[],framebuffers:[],renderbuffers:[],textures:[],uniforms:[],shaders:[],vaos:[],contexts:[],offscreenCanvases:{},timerQueriesEXT:[],queries:[],samplers:[],transformFeedbacks:[],syncs:[],programInfos:{},stringCache:{},stringiCache:{},unpackAlignment:4,recordError:function recordError(errorCode) {
  2745. if (!GL.lastError) {
  2746. GL.lastError = errorCode;
  2747. }
  2748. },getNewId:function(table) {
  2749. var ret = GL.counter++;
  2750. for (var i = table.length; i < ret; i++) {
  2751. table[i] = null;
  2752. }
  2753. return ret;
  2754. },getSource:function(shader, count, string, length) {
  2755. var source = '';
  2756. for (var i = 0; i < count; ++i) {
  2757. var len = length ? HEAP32[(((length)+(i*4))>>2)] : -1;
  2758. source += UTF8ToString(HEAP32[(((string)+(i*4))>>2)], len < 0 ? undefined : len);
  2759. }
  2760. return source;
  2761. },createContext:function(canvas, webGLContextAttributes) {
  2762. var ctx =
  2763. (webGLContextAttributes.majorVersion > 1)
  2764. ?
  2765. canvas.getContext("webgl2", webGLContextAttributes)
  2766. :
  2767. (canvas.getContext("webgl", webGLContextAttributes)
  2768. // https://caniuse.com/#feat=webgl
  2769. );
  2770. if (!ctx) return 0;
  2771. var handle = GL.registerContext(ctx, webGLContextAttributes);
  2772. return handle;
  2773. },registerContext:function(ctx, webGLContextAttributes) {
  2774. // without pthreads a context is just an integer ID
  2775. var handle = GL.getNewId(GL.contexts);
  2776. var context = {
  2777. handle: handle,
  2778. attributes: webGLContextAttributes,
  2779. version: webGLContextAttributes.majorVersion,
  2780. GLctx: ctx
  2781. };
  2782. // Store the created context object so that we can access the context given a canvas without having to pass the parameters again.
  2783. if (ctx.canvas) ctx.canvas.GLctxObject = context;
  2784. GL.contexts[handle] = context;
  2785. if (typeof webGLContextAttributes.enableExtensionsByDefault === 'undefined' || webGLContextAttributes.enableExtensionsByDefault) {
  2786. GL.initExtensions(context);
  2787. }
  2788. return handle;
  2789. },makeContextCurrent:function(contextHandle) {
  2790. GL.currentContext = GL.contexts[contextHandle]; // Active Emscripten GL layer context object.
  2791. Module.ctx = GLctx = GL.currentContext && GL.currentContext.GLctx; // Active WebGL context object.
  2792. return !(contextHandle && !GLctx);
  2793. },getContext:function(contextHandle) {
  2794. return GL.contexts[contextHandle];
  2795. },deleteContext:function(contextHandle) {
  2796. if (GL.currentContext === GL.contexts[contextHandle]) GL.currentContext = null;
  2797. 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.
  2798. 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.
  2799. GL.contexts[contextHandle] = null;
  2800. },initExtensions:function(context) {
  2801. // If this function is called without a specific context object, init the extensions of the currently active context.
  2802. if (!context) context = GL.currentContext;
  2803. if (context.initExtensionsDone) return;
  2804. context.initExtensionsDone = true;
  2805. var GLctx = context.GLctx;
  2806. // Detect the presence of a few extensions manually, this GL interop layer itself will need to know if they exist.
  2807. // Extensions that are only available in WebGL 1 (the calls will be no-ops if called on a WebGL 2 context active)
  2808. __webgl_enable_ANGLE_instanced_arrays(GLctx);
  2809. __webgl_enable_OES_vertex_array_object(GLctx);
  2810. __webgl_enable_WEBGL_draw_buffers(GLctx);
  2811. // Extensions that are available from WebGL >= 2 (no-op if called on a WebGL 1 context active)
  2812. __webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance(GLctx);
  2813. __webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance(GLctx);
  2814. GLctx.disjointTimerQueryExt = GLctx.getExtension("EXT_disjoint_timer_query");
  2815. __webgl_enable_WEBGL_multi_draw(GLctx);
  2816. // .getSupportedExtensions() can return null if context is lost, so coerce to empty array.
  2817. var exts = GLctx.getSupportedExtensions() || [];
  2818. exts.forEach(function(ext) {
  2819. // WEBGL_lose_context, WEBGL_debug_renderer_info and WEBGL_debug_shaders are not enabled by default.
  2820. if (ext.indexOf('lose_context') < 0 && ext.indexOf('debug') < 0) {
  2821. // Call .getExtension() to enable that extension permanently.
  2822. GLctx.getExtension(ext);
  2823. }
  2824. });
  2825. },populateUniformTable:function(program) {
  2826. var p = GL.programs[program];
  2827. var ptable = GL.programInfos[program] = {
  2828. uniforms: {},
  2829. maxUniformLength: 0, // This is eagerly computed below, since we already enumerate all uniforms anyway.
  2830. maxAttributeLength: -1, // This is lazily computed and cached, computed when/if first asked, "-1" meaning not computed yet.
  2831. maxUniformBlockNameLength: -1 // Lazily computed as well
  2832. };
  2833. var utable = ptable.uniforms;
  2834. // A program's uniform table maps the string name of an uniform to an integer location of that uniform.
  2835. // The global GL.uniforms map maps integer locations to WebGLUniformLocations.
  2836. var numUniforms = GLctx.getProgramParameter(p, 0x8B86/*GL_ACTIVE_UNIFORMS*/);
  2837. for (var i = 0; i < numUniforms; ++i) {
  2838. var u = GLctx.getActiveUniform(p, i);
  2839. var name = u.name;
  2840. ptable.maxUniformLength = Math.max(ptable.maxUniformLength, name.length+1);
  2841. // If we are dealing with an array, e.g. vec4 foo[3], strip off the array index part to canonicalize that "foo", "foo[]",
  2842. // and "foo[0]" will mean the same. Loop below will populate foo[1] and foo[2].
  2843. if (name.slice(-1) == ']') {
  2844. name = name.slice(0, name.lastIndexOf('['));
  2845. }
  2846. // Optimize memory usage slightly: If we have an array of uniforms, e.g. 'vec3 colors[3];', then
  2847. // only store the string 'colors' in utable, and 'colors[0]', 'colors[1]' and 'colors[2]' will be parsed as 'colors'+i.
  2848. // Note that for the GL.uniforms table, we still need to fetch the all WebGLUniformLocations for all the indices.
  2849. var loc = GLctx.getUniformLocation(p, name);
  2850. if (loc) {
  2851. var id = GL.getNewId(GL.uniforms);
  2852. utable[name] = [u.size, id];
  2853. GL.uniforms[id] = loc;
  2854. for (var j = 1; j < u.size; ++j) {
  2855. var n = name + '['+j+']';
  2856. loc = GLctx.getUniformLocation(p, n);
  2857. id = GL.getNewId(GL.uniforms);
  2858. GL.uniforms[id] = loc;
  2859. }
  2860. }
  2861. }
  2862. }};
  2863. var __emscripten_webgl_power_preferences=['default', 'low-power', 'high-performance'];
  2864. function _emscripten_webgl_do_create_context(target, attributes) {
  2865. var a = attributes >> 2;
  2866. var powerPreference = HEAP32[a + (24>>2)];
  2867. var contextAttributes = {
  2868. 'alpha': !!HEAP32[a + (0>>2)],
  2869. 'depth': !!HEAP32[a + (4>>2)],
  2870. 'stencil': !!HEAP32[a + (8>>2)],
  2871. 'antialias': !!HEAP32[a + (12>>2)],
  2872. 'premultipliedAlpha': !!HEAP32[a + (16>>2)],
  2873. 'preserveDrawingBuffer': !!HEAP32[a + (20>>2)],
  2874. 'powerPreference': __emscripten_webgl_power_preferences[powerPreference],
  2875. 'failIfMajorPerformanceCaveat': !!HEAP32[a + (28>>2)],
  2876. // The following are not predefined WebGL context attributes in the WebGL specification, so the property names can be minified by Closure.
  2877. majorVersion: HEAP32[a + (32>>2)],
  2878. minorVersion: HEAP32[a + (36>>2)],
  2879. enableExtensionsByDefault: HEAP32[a + (40>>2)],
  2880. explicitSwapControl: HEAP32[a + (44>>2)],
  2881. proxyContextToMainThread: HEAP32[a + (48>>2)],
  2882. renderViaOffscreenBackBuffer: HEAP32[a + (52>>2)]
  2883. };
  2884. var canvas = findCanvasEventTarget(target);
  2885. if (!canvas) {
  2886. return 0;
  2887. }
  2888. if (contextAttributes.explicitSwapControl) {
  2889. return 0;
  2890. }
  2891. var contextHandle = GL.createContext(canvas, contextAttributes);
  2892. return contextHandle;
  2893. }
  2894. function _emscripten_webgl_create_context(a0,a1
  2895. ) {
  2896. return _emscripten_webgl_do_create_context(a0,a1);
  2897. }
  2898. function _emscripten_webgl_init_context_attributes(attributes) {
  2899. var a = attributes >> 2;
  2900. for(var i = 0; i < (56>>2); ++i) {
  2901. HEAP32[a+i] = 0;
  2902. }
  2903. HEAP32[a + (0>>2)] =
  2904. HEAP32[a + (4>>2)] =
  2905. HEAP32[a + (12>>2)] =
  2906. HEAP32[a + (16>>2)] =
  2907. HEAP32[a + (32>>2)] =
  2908. HEAP32[a + (40>>2)] = 1;
  2909. }
  2910. function _emscripten_webgl_make_context_current(contextHandle) {
  2911. var success = GL.makeContextCurrent(contextHandle);
  2912. return success ? 0 : -5;
  2913. }
  2914. function flush_NO_FILESYSTEM() {
  2915. // flush anything remaining in the buffers during shutdown
  2916. if (typeof _fflush !== 'undefined') _fflush(0);
  2917. var buffers = SYSCALLS.buffers;
  2918. if (buffers[1].length) SYSCALLS.printChar(1, 10);
  2919. if (buffers[2].length) SYSCALLS.printChar(2, 10);
  2920. }
  2921. var SYSCALLS={mappings:{},buffers:[null,[],[]],printChar:function(stream, curr) {
  2922. var buffer = SYSCALLS.buffers[stream];
  2923. if (curr === 0 || curr === 10) {
  2924. (stream === 1 ? out : err)(UTF8ArrayToString(buffer, 0));
  2925. buffer.length = 0;
  2926. } else {
  2927. buffer.push(curr);
  2928. }
  2929. },varargs:undefined,get:function() {
  2930. SYSCALLS.varargs += 4;
  2931. var ret = HEAP32[(((SYSCALLS.varargs)-(4))>>2)];
  2932. return ret;
  2933. },getStr:function(ptr) {
  2934. var ret = UTF8ToString(ptr);
  2935. return ret;
  2936. },get64:function(low, high) {
  2937. return low;
  2938. }};
  2939. function _fd_write(fd, iov, iovcnt, pnum) {
  2940. // hack to support printf in SYSCALLS_REQUIRE_FILESYSTEM=0
  2941. var num = 0;
  2942. for (var i = 0; i < iovcnt; i++) {
  2943. var ptr = HEAP32[(((iov)+(i*8))>>2)];
  2944. var len = HEAP32[(((iov)+(i*8 + 4))>>2)];
  2945. for (var j = 0; j < len; j++) {
  2946. SYSCALLS.printChar(fd, HEAPU8[ptr+j]);
  2947. }
  2948. num += len;
  2949. }
  2950. HEAP32[((pnum)>>2)] = num
  2951. return 0;
  2952. }
  2953. function _glActiveTexture(x0) { GLctx['activeTexture'](x0) }
  2954. function _glAttachShader(program, shader) {
  2955. GLctx.attachShader(GL.programs[program],
  2956. GL.shaders[shader]);
  2957. }
  2958. function _glBindBuffer(target, buffer) {
  2959. if (target == 0x88EB /*GL_PIXEL_PACK_BUFFER*/) {
  2960. // In WebGL 2 glReadPixels entry point, we need to use a different WebGL 2 API function call when a buffer is bound to
  2961. // GL_PIXEL_PACK_BUFFER_BINDING point, so must keep track whether that binding point is non-null to know what is
  2962. // the proper API function to call.
  2963. GLctx.currentPixelPackBufferBinding = buffer;
  2964. } else if (target == 0x88EC /*GL_PIXEL_UNPACK_BUFFER*/) {
  2965. // In WebGL 2 gl(Compressed)Tex(Sub)Image[23]D entry points, we need to
  2966. // use a different WebGL 2 API function call when a buffer is bound to
  2967. // GL_PIXEL_UNPACK_BUFFER_BINDING point, so must keep track whether that
  2968. // binding point is non-null to know what is the proper API function to
  2969. // call.
  2970. GLctx.currentPixelUnpackBufferBinding = buffer;
  2971. }
  2972. GLctx.bindBuffer(target, GL.buffers[buffer]);
  2973. }
  2974. function _glBindBufferRange(target, index, buffer, offset, ptrsize) {
  2975. GLctx['bindBufferRange'](target, index, GL.buffers[buffer], offset, ptrsize);
  2976. }
  2977. function _glBindFramebuffer(target, framebuffer) {
  2978. GLctx.bindFramebuffer(target, GL.framebuffers[framebuffer]);
  2979. }
  2980. function _glBindRenderbuffer(target, renderbuffer) {
  2981. GLctx.bindRenderbuffer(target, GL.renderbuffers[renderbuffer]);
  2982. }
  2983. function _glBindTexture(target, texture) {
  2984. GLctx.bindTexture(target, GL.textures[texture]);
  2985. }
  2986. function _glBindVertexArray(vao) {
  2987. GLctx['bindVertexArray'](GL.vaos[vao]);
  2988. }
  2989. function _glBlendEquation(x0) { GLctx['blendEquation'](x0) }
  2990. function _glBlendFunc(x0, x1) { GLctx['blendFunc'](x0, x1) }
  2991. function _glBufferData(target, size, data, usage) {
  2992. if (GL.currentContext.version >= 2) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
  2993. if (data) {
  2994. GLctx.bufferData(target, HEAPU8, usage, data, size);
  2995. } else {
  2996. GLctx.bufferData(target, size, usage);
  2997. }
  2998. } else {
  2999. // 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
  3000. // randomly mixing both uses in calling code, to avoid any potential JS engine JIT issues.
  3001. GLctx.bufferData(target, data ? HEAPU8.subarray(data, data+size) : size, usage);
  3002. }
  3003. }
  3004. function _glBufferSubData(target, offset, size, data) {
  3005. if (GL.currentContext.version >= 2) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
  3006. GLctx.bufferSubData(target, offset, HEAPU8, data, size);
  3007. return;
  3008. }
  3009. GLctx.bufferSubData(target, offset, HEAPU8.subarray(data, data+size));
  3010. }
  3011. function _glClear(x0) { GLctx['clear'](x0) }
  3012. function _glClearColor(x0, x1, x2, x3) { GLctx['clearColor'](x0, x1, x2, x3) }
  3013. function _glCompileShader(shader) {
  3014. GLctx.compileShader(GL.shaders[shader]);
  3015. }
  3016. function _glCreateProgram() {
  3017. var id = GL.getNewId(GL.programs);
  3018. var program = GLctx.createProgram();
  3019. program.name = id;
  3020. GL.programs[id] = program;
  3021. return id;
  3022. }
  3023. function _glCreateShader(shaderType) {
  3024. var id = GL.getNewId(GL.shaders);
  3025. GL.shaders[id] = GLctx.createShader(shaderType);
  3026. return id;
  3027. }
  3028. function _glCullFace(x0) { GLctx['cullFace'](x0) }
  3029. function _glDeleteProgram(id) {
  3030. if (!id) return;
  3031. var program = GL.programs[id];
  3032. if (!program) { // glDeleteProgram actually signals an error when deleting a nonexisting object, unlike some other GL delete functions.
  3033. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  3034. return;
  3035. }
  3036. GLctx.deleteProgram(program);
  3037. program.name = 0;
  3038. GL.programs[id] = null;
  3039. GL.programInfos[id] = null;
  3040. }
  3041. function _glDeleteShader(id) {
  3042. if (!id) return;
  3043. var shader = GL.shaders[id];
  3044. if (!shader) { // glDeleteShader actually signals an error when deleting a nonexisting object, unlike some other GL delete functions.
  3045. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  3046. return;
  3047. }
  3048. GLctx.deleteShader(shader);
  3049. GL.shaders[id] = null;
  3050. }
  3051. function _glDepthFunc(x0) { GLctx['depthFunc'](x0) }
  3052. function _glDisable(x0) { GLctx['disable'](x0) }
  3053. function _glDrawArrays(mode, first, count) {
  3054. GLctx.drawArrays(mode, first, count);
  3055. }
  3056. function _glDrawArraysInstanced(mode, first, count, primcount) {
  3057. GLctx['drawArraysInstanced'](mode, first, count, primcount);
  3058. }
  3059. function _glDrawElements(mode, count, type, indices) {
  3060. GLctx.drawElements(mode, count, type, indices);
  3061. }
  3062. function _glDrawElementsInstanced(mode, count, type, indices, primcount) {
  3063. GLctx['drawElementsInstanced'](mode, count, type, indices, primcount);
  3064. }
  3065. function _glEnable(x0) { GLctx['enable'](x0) }
  3066. function _glEnableVertexAttribArray(index) {
  3067. GLctx.enableVertexAttribArray(index);
  3068. }
  3069. function _glFramebufferTexture2D(target, attachment, textarget, texture, level) {
  3070. GLctx.framebufferTexture2D(target, attachment, textarget,
  3071. GL.textures[texture], level);
  3072. }
  3073. function _glFrontFace(x0) { GLctx['frontFace'](x0) }
  3074. function __glGenObject(n, buffers, createFunction, objectTable
  3075. ) {
  3076. for (var i = 0; i < n; i++) {
  3077. var buffer = GLctx[createFunction]();
  3078. var id = buffer && GL.getNewId(objectTable);
  3079. if (buffer) {
  3080. buffer.name = id;
  3081. objectTable[id] = buffer;
  3082. } else {
  3083. GL.recordError(0x502 /* GL_INVALID_OPERATION */);
  3084. }
  3085. HEAP32[(((buffers)+(i*4))>>2)] = id;
  3086. }
  3087. }
  3088. function _glGenBuffers(n, buffers) {
  3089. __glGenObject(n, buffers, 'createBuffer', GL.buffers
  3090. );
  3091. }
  3092. function _glGenFramebuffers(n, ids) {
  3093. __glGenObject(n, ids, 'createFramebuffer', GL.framebuffers
  3094. );
  3095. }
  3096. function _glGenTextures(n, textures) {
  3097. __glGenObject(n, textures, 'createTexture', GL.textures
  3098. );
  3099. }
  3100. function _glGenVertexArrays(n, arrays) {
  3101. __glGenObject(n, arrays, 'createVertexArray', GL.vaos
  3102. );
  3103. }
  3104. function _glGenerateMipmap(x0) { GLctx['generateMipmap'](x0) }
  3105. function writeI53ToI64(ptr, num) {
  3106. HEAPU32[ptr>>2] = num;
  3107. HEAPU32[ptr+4>>2] = (num - HEAPU32[ptr>>2])/4294967296;
  3108. }
  3109. function emscriptenWebGLGet(name_, p, type) {
  3110. // Guard against user passing a null pointer.
  3111. // Note that GLES2 spec does not say anything about how passing a null pointer should be treated.
  3112. // Testing on desktop core GL 3, the application crashes on glGetIntegerv to a null pointer, but
  3113. // better to report an error instead of doing anything random.
  3114. if (!p) {
  3115. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  3116. return;
  3117. }
  3118. var ret = undefined;
  3119. switch(name_) { // Handle a few trivial GLES values
  3120. case 0x8DFA: // GL_SHADER_COMPILER
  3121. ret = 1;
  3122. break;
  3123. case 0x8DF8: // GL_SHADER_BINARY_FORMATS
  3124. if (type != 0 && type != 1) {
  3125. GL.recordError(0x500); // GL_INVALID_ENUM
  3126. }
  3127. return; // Do not write anything to the out pointer, since no binary formats are supported.
  3128. case 0x87FE: // GL_NUM_PROGRAM_BINARY_FORMATS
  3129. case 0x8DF9: // GL_NUM_SHADER_BINARY_FORMATS
  3130. ret = 0;
  3131. break;
  3132. case 0x86A2: // GL_NUM_COMPRESSED_TEXTURE_FORMATS
  3133. // 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),
  3134. // so implement it ourselves to allow C++ GLES2 code get the length.
  3135. var formats = GLctx.getParameter(0x86A3 /*GL_COMPRESSED_TEXTURE_FORMATS*/);
  3136. ret = formats ? formats.length : 0;
  3137. break;
  3138. case 0x821D: // GL_NUM_EXTENSIONS
  3139. if (GL.currentContext.version < 2) {
  3140. GL.recordError(0x502 /* GL_INVALID_OPERATION */); // Calling GLES3/WebGL2 function with a GLES2/WebGL1 context
  3141. return;
  3142. }
  3143. // .getSupportedExtensions() can return null if context is lost, so coerce to empty array.
  3144. var exts = GLctx.getSupportedExtensions() || [];
  3145. ret = 2 * exts.length; // each extension is duplicated, first in unprefixed WebGL form, and then a second time with "GL_" prefix.
  3146. break;
  3147. case 0x821B: // GL_MAJOR_VERSION
  3148. case 0x821C: // GL_MINOR_VERSION
  3149. if (GL.currentContext.version < 2) {
  3150. GL.recordError(0x500); // GL_INVALID_ENUM
  3151. return;
  3152. }
  3153. ret = name_ == 0x821B ? 3 : 0; // return version 3.0
  3154. break;
  3155. }
  3156. if (ret === undefined) {
  3157. var result = GLctx.getParameter(name_);
  3158. switch (typeof(result)) {
  3159. case "number":
  3160. ret = result;
  3161. break;
  3162. case "boolean":
  3163. ret = result ? 1 : 0;
  3164. break;
  3165. case "string":
  3166. GL.recordError(0x500); // GL_INVALID_ENUM
  3167. return;
  3168. case "object":
  3169. if (result === null) {
  3170. // null is a valid result for some (e.g., which buffer is bound - perhaps nothing is bound), but otherwise
  3171. // can mean an invalid name_, which we need to report as an error
  3172. switch(name_) {
  3173. case 0x8894: // ARRAY_BUFFER_BINDING
  3174. case 0x8B8D: // CURRENT_PROGRAM
  3175. case 0x8895: // ELEMENT_ARRAY_BUFFER_BINDING
  3176. case 0x8CA6: // FRAMEBUFFER_BINDING or DRAW_FRAMEBUFFER_BINDING
  3177. case 0x8CA7: // RENDERBUFFER_BINDING
  3178. case 0x8069: // TEXTURE_BINDING_2D
  3179. case 0x85B5: // WebGL 2 GL_VERTEX_ARRAY_BINDING, or WebGL 1 extension OES_vertex_array_object GL_VERTEX_ARRAY_BINDING_OES
  3180. case 0x8F36: // COPY_READ_BUFFER_BINDING or COPY_READ_BUFFER
  3181. case 0x8F37: // COPY_WRITE_BUFFER_BINDING or COPY_WRITE_BUFFER
  3182. case 0x88ED: // PIXEL_PACK_BUFFER_BINDING
  3183. case 0x88EF: // PIXEL_UNPACK_BUFFER_BINDING
  3184. case 0x8CAA: // READ_FRAMEBUFFER_BINDING
  3185. case 0x8919: // SAMPLER_BINDING
  3186. case 0x8C1D: // TEXTURE_BINDING_2D_ARRAY
  3187. case 0x806A: // TEXTURE_BINDING_3D
  3188. case 0x8E25: // TRANSFORM_FEEDBACK_BINDING
  3189. case 0x8C8F: // TRANSFORM_FEEDBACK_BUFFER_BINDING
  3190. case 0x8A28: // UNIFORM_BUFFER_BINDING
  3191. case 0x8514: { // TEXTURE_BINDING_CUBE_MAP
  3192. ret = 0;
  3193. break;
  3194. }
  3195. default: {
  3196. GL.recordError(0x500); // GL_INVALID_ENUM
  3197. return;
  3198. }
  3199. }
  3200. } else if (result instanceof Float32Array ||
  3201. result instanceof Uint32Array ||
  3202. result instanceof Int32Array ||
  3203. result instanceof Array) {
  3204. for (var i = 0; i < result.length; ++i) {
  3205. switch (type) {
  3206. case 0: HEAP32[(((p)+(i*4))>>2)] = result[i]; break;
  3207. case 2: HEAPF32[(((p)+(i*4))>>2)] = result[i]; break;
  3208. case 4: HEAP8[(((p)+(i))>>0)] = result[i] ? 1 : 0; break;
  3209. }
  3210. }
  3211. return;
  3212. } else {
  3213. try {
  3214. ret = result.name | 0;
  3215. } catch(e) {
  3216. GL.recordError(0x500); // GL_INVALID_ENUM
  3217. err('GL_INVALID_ENUM in glGet' + type + 'v: Unknown object returned from WebGL getParameter(' + name_ + ')! (error: ' + e + ')');
  3218. return;
  3219. }
  3220. }
  3221. break;
  3222. default:
  3223. GL.recordError(0x500); // GL_INVALID_ENUM
  3224. err('GL_INVALID_ENUM in glGet' + type + 'v: Native code calling glGet' + type + 'v(' + name_ + ') and it returns ' + result + ' of type ' + typeof(result) + '!');
  3225. return;
  3226. }
  3227. }
  3228. switch (type) {
  3229. case 1: writeI53ToI64(p, ret); break;
  3230. case 0: HEAP32[((p)>>2)] = ret; break;
  3231. case 2: HEAPF32[((p)>>2)] = ret; break;
  3232. case 4: HEAP8[((p)>>0)] = ret ? 1 : 0; break;
  3233. }
  3234. }
  3235. function _glGetIntegerv(name_, p) {
  3236. emscriptenWebGLGet(name_, p, 0);
  3237. }
  3238. function _glGetProgramInfoLog(program, maxLength, length, infoLog) {
  3239. var log = GLctx.getProgramInfoLog(GL.programs[program]);
  3240. if (log === null) log = '(unknown error)';
  3241. var numBytesWrittenExclNull = (maxLength > 0 && infoLog) ? stringToUTF8(log, infoLog, maxLength) : 0;
  3242. if (length) HEAP32[((length)>>2)] = numBytesWrittenExclNull;
  3243. }
  3244. function _glGetProgramiv(program, pname, p) {
  3245. if (!p) {
  3246. // GLES2 specification does not specify how to behave if p is a null pointer. Since calling this function does not make sense
  3247. // if p == null, issue a GL error to notify user about it.
  3248. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  3249. return;
  3250. }
  3251. if (program >= GL.counter) {
  3252. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  3253. return;
  3254. }
  3255. var ptable = GL.programInfos[program];
  3256. if (!ptable) {
  3257. GL.recordError(0x502 /* GL_INVALID_OPERATION */);
  3258. return;
  3259. }
  3260. if (pname == 0x8B84) { // GL_INFO_LOG_LENGTH
  3261. var log = GLctx.getProgramInfoLog(GL.programs[program]);
  3262. if (log === null) log = '(unknown error)';
  3263. HEAP32[((p)>>2)] = log.length + 1;
  3264. } else if (pname == 0x8B87 /* GL_ACTIVE_UNIFORM_MAX_LENGTH */) {
  3265. HEAP32[((p)>>2)] = ptable.maxUniformLength;
  3266. } else if (pname == 0x8B8A /* GL_ACTIVE_ATTRIBUTE_MAX_LENGTH */) {
  3267. if (ptable.maxAttributeLength == -1) {
  3268. program = GL.programs[program];
  3269. var numAttribs = GLctx.getProgramParameter(program, 0x8B89/*GL_ACTIVE_ATTRIBUTES*/);
  3270. ptable.maxAttributeLength = 0; // Spec says if there are no active attribs, 0 must be returned.
  3271. for (var i = 0; i < numAttribs; ++i) {
  3272. var activeAttrib = GLctx.getActiveAttrib(program, i);
  3273. ptable.maxAttributeLength = Math.max(ptable.maxAttributeLength, activeAttrib.name.length+1);
  3274. }
  3275. }
  3276. HEAP32[((p)>>2)] = ptable.maxAttributeLength;
  3277. } else if (pname == 0x8A35 /* GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH */) {
  3278. if (ptable.maxUniformBlockNameLength == -1) {
  3279. program = GL.programs[program];
  3280. var numBlocks = GLctx.getProgramParameter(program, 0x8A36/*GL_ACTIVE_UNIFORM_BLOCKS*/);
  3281. ptable.maxUniformBlockNameLength = 0;
  3282. for (var i = 0; i < numBlocks; ++i) {
  3283. var activeBlockName = GLctx.getActiveUniformBlockName(program, i);
  3284. ptable.maxUniformBlockNameLength = Math.max(ptable.maxUniformBlockNameLength, activeBlockName.length+1);
  3285. }
  3286. }
  3287. HEAP32[((p)>>2)] = ptable.maxUniformBlockNameLength;
  3288. } else {
  3289. HEAP32[((p)>>2)] = GLctx.getProgramParameter(GL.programs[program], pname);
  3290. }
  3291. }
  3292. function _glGetShaderInfoLog(shader, maxLength, length, infoLog) {
  3293. var log = GLctx.getShaderInfoLog(GL.shaders[shader]);
  3294. if (log === null) log = '(unknown error)';
  3295. var numBytesWrittenExclNull = (maxLength > 0 && infoLog) ? stringToUTF8(log, infoLog, maxLength) : 0;
  3296. if (length) HEAP32[((length)>>2)] = numBytesWrittenExclNull;
  3297. }
  3298. function _glGetShaderiv(shader, pname, p) {
  3299. if (!p) {
  3300. // GLES2 specification does not specify how to behave if p is a null pointer. Since calling this function does not make sense
  3301. // if p == null, issue a GL error to notify user about it.
  3302. GL.recordError(0x501 /* GL_INVALID_VALUE */);
  3303. return;
  3304. }
  3305. if (pname == 0x8B84) { // GL_INFO_LOG_LENGTH
  3306. var log = GLctx.getShaderInfoLog(GL.shaders[shader]);
  3307. if (log === null) log = '(unknown error)';
  3308. // The GLES2 specification says that if the shader has an empty info log,
  3309. // a value of 0 is returned. Otherwise the log has a null char appended.
  3310. // (An empty string is falsey, so we can just check that instead of
  3311. // looking at log.length.)
  3312. var logLength = log ? log.length + 1 : 0;
  3313. HEAP32[((p)>>2)] = logLength;
  3314. } else if (pname == 0x8B88) { // GL_SHADER_SOURCE_LENGTH
  3315. var source = GLctx.getShaderSource(GL.shaders[shader]);
  3316. // source may be a null, or the empty string, both of which are falsey
  3317. // values that we report a 0 length for.
  3318. var sourceLength = source ? source.length + 1 : 0;
  3319. HEAP32[((p)>>2)] = sourceLength;
  3320. } else {
  3321. HEAP32[((p)>>2)] = GLctx.getShaderParameter(GL.shaders[shader], pname);
  3322. }
  3323. }
  3324. function _glGetUniformBlockIndex(program, uniformBlockName) {
  3325. return GLctx['getUniformBlockIndex'](GL.programs[program], UTF8ToString(uniformBlockName));
  3326. }
  3327. function _glGetUniformLocation(program, name) {
  3328. name = UTF8ToString(name);
  3329. var arrayIndex = 0;
  3330. // If user passed an array accessor "[index]", parse the array index off the accessor.
  3331. if (name[name.length - 1] == ']') {
  3332. var leftBrace = name.lastIndexOf('[');
  3333. arrayIndex = name[leftBrace+1] != ']' ? jstoi_q(name.slice(leftBrace + 1)) : 0; // "index]", parseInt will ignore the ']' at the end; but treat "foo[]" as "foo[0]"
  3334. name = name.slice(0, leftBrace);
  3335. }
  3336. var uniformInfo = GL.programInfos[program] && GL.programInfos[program].uniforms[name]; // returns pair [ dimension_of_uniform_array, uniform_location ]
  3337. if (uniformInfo && arrayIndex >= 0 && arrayIndex < uniformInfo[0]) { // Check if user asked for an out-of-bounds element, i.e. for 'vec4 colors[3];' user could ask for 'colors[10]' which should return -1.
  3338. return uniformInfo[1] + arrayIndex;
  3339. } else {
  3340. return -1;
  3341. }
  3342. }
  3343. function _glLinkProgram(program) {
  3344. GLctx.linkProgram(GL.programs[program]);
  3345. GL.populateUniformTable(program);
  3346. }
  3347. function _glScissor(x0, x1, x2, x3) { GLctx['scissor'](x0, x1, x2, x3) }
  3348. function _glShaderSource(shader, count, string, length) {
  3349. var source = GL.getSource(shader, count, string, length);
  3350. GLctx.shaderSource(GL.shaders[shader], source);
  3351. }
  3352. function _glStencilFunc(x0, x1, x2) { GLctx['stencilFunc'](x0, x1, x2) }
  3353. function _glStencilMask(x0) { GLctx['stencilMask'](x0) }
  3354. function _glStencilOp(x0, x1, x2) { GLctx['stencilOp'](x0, x1, x2) }
  3355. function computeUnpackAlignedImageSize(width, height, sizePerPixel, alignment) {
  3356. function roundedToNextMultipleOf(x, y) {
  3357. return (x + y - 1) & -y;
  3358. }
  3359. var plainRowSize = width * sizePerPixel;
  3360. var alignedRowSize = roundedToNextMultipleOf(plainRowSize, alignment);
  3361. return height * alignedRowSize;
  3362. }
  3363. function __colorChannelsInGlTextureFormat(format) {
  3364. // Micro-optimizations for size: map format to size by subtracting smallest enum value (0x1902) from all values first.
  3365. // Also omit the most common size value (1) from the list, which is assumed by formats not on the list.
  3366. var colorChannels = {
  3367. // 0x1902 /* GL_DEPTH_COMPONENT */ - 0x1902: 1,
  3368. // 0x1906 /* GL_ALPHA */ - 0x1902: 1,
  3369. 5: 3,
  3370. 6: 4,
  3371. // 0x1909 /* GL_LUMINANCE */ - 0x1902: 1,
  3372. 8: 2,
  3373. 29502: 3,
  3374. 29504: 4,
  3375. // 0x1903 /* GL_RED */ - 0x1902: 1,
  3376. 26917: 2,
  3377. 26918: 2,
  3378. // 0x8D94 /* GL_RED_INTEGER */ - 0x1902: 1,
  3379. 29846: 3,
  3380. 29847: 4
  3381. };
  3382. return colorChannels[format - 0x1902]||1;
  3383. }
  3384. function heapObjectForWebGLType(type) {
  3385. // Micro-optimization for size: Subtract lowest GL enum number (0x1400/* GL_BYTE */) from type to compare
  3386. // smaller values for the heap, for shorter generated code size.
  3387. // Also the type HEAPU16 is not tested for explicitly, but any unrecognized type will return out HEAPU16.
  3388. // (since most types are HEAPU16)
  3389. type -= 0x1400;
  3390. if (type == 0) return HEAP8;
  3391. if (type == 1) return HEAPU8;
  3392. if (type == 2) return HEAP16;
  3393. if (type == 4) return HEAP32;
  3394. if (type == 6) return HEAPF32;
  3395. if (type == 5
  3396. || type == 28922
  3397. || type == 28520
  3398. || type == 30779
  3399. || type == 30782
  3400. )
  3401. return HEAPU32;
  3402. return HEAPU16;
  3403. }
  3404. function heapAccessShiftForWebGLHeap(heap) {
  3405. return 31 - Math.clz32(heap.BYTES_PER_ELEMENT);
  3406. }
  3407. function emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, internalFormat) {
  3408. var heap = heapObjectForWebGLType(type);
  3409. var shift = heapAccessShiftForWebGLHeap(heap);
  3410. var byteSize = 1<<shift;
  3411. var sizePerPixel = __colorChannelsInGlTextureFormat(format) * byteSize;
  3412. var bytes = computeUnpackAlignedImageSize(width, height, sizePerPixel, GL.unpackAlignment);
  3413. return heap.subarray(pixels >> shift, pixels + bytes >> shift);
  3414. }
  3415. function _glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels) {
  3416. if (GL.currentContext.version >= 2) {
  3417. // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
  3418. if (GLctx.currentPixelUnpackBufferBinding) {
  3419. GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, pixels);
  3420. } else if (pixels) {
  3421. var heap = heapObjectForWebGLType(type);
  3422. GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, heap, pixels >> heapAccessShiftForWebGLHeap(heap));
  3423. } else {
  3424. GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, null);
  3425. }
  3426. return;
  3427. }
  3428. GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, pixels ? emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, internalFormat) : null);
  3429. }
  3430. function _glTexParameteri(x0, x1, x2) { GLctx['texParameteri'](x0, x1, x2) }
  3431. function _glUniform1f(location, v0) {
  3432. GLctx.uniform1f(GL.uniforms[location], v0);
  3433. }
  3434. function _glUniform1i(location, v0) {
  3435. GLctx.uniform1i(GL.uniforms[location], v0);
  3436. }
  3437. function _glUniform2f(location, v0, v1) {
  3438. GLctx.uniform2f(GL.uniforms[location], v0, v1);
  3439. }
  3440. function _glUniform3f(location, v0, v1, v2) {
  3441. GLctx.uniform3f(GL.uniforms[location], v0, v1, v2);
  3442. }
  3443. function _glUniform4f(location, v0, v1, v2, v3) {
  3444. GLctx.uniform4f(GL.uniforms[location], v0, v1, v2, v3);
  3445. }
  3446. function _glUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding) {
  3447. program = GL.programs[program];
  3448. GLctx['uniformBlockBinding'](program, uniformBlockIndex, uniformBlockBinding);
  3449. }
  3450. var miniTempWebGLFloatBuffers=[];
  3451. function _glUniformMatrix4fv(location, count, transpose, value) {
  3452. if (GL.currentContext.version >= 2) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
  3453. GLctx.uniformMatrix4fv(GL.uniforms[location], !!transpose, HEAPF32, value>>2, count*16);
  3454. return;
  3455. }
  3456. if (count <= 18) {
  3457. // avoid allocation when uploading few enough uniforms
  3458. var view = miniTempWebGLFloatBuffers[16*count-1];
  3459. // hoist the heap out of the loop for size and for pthreads+growth.
  3460. var heap = HEAPF32;
  3461. value >>= 2;
  3462. for (var i = 0; i < 16 * count; i += 16) {
  3463. var dst = value + i;
  3464. view[i] = heap[dst];
  3465. view[i + 1] = heap[dst + 1];
  3466. view[i + 2] = heap[dst + 2];
  3467. view[i + 3] = heap[dst + 3];
  3468. view[i + 4] = heap[dst + 4];
  3469. view[i + 5] = heap[dst + 5];
  3470. view[i + 6] = heap[dst + 6];
  3471. view[i + 7] = heap[dst + 7];
  3472. view[i + 8] = heap[dst + 8];
  3473. view[i + 9] = heap[dst + 9];
  3474. view[i + 10] = heap[dst + 10];
  3475. view[i + 11] = heap[dst + 11];
  3476. view[i + 12] = heap[dst + 12];
  3477. view[i + 13] = heap[dst + 13];
  3478. view[i + 14] = heap[dst + 14];
  3479. view[i + 15] = heap[dst + 15];
  3480. }
  3481. } else
  3482. {
  3483. var view = HEAPF32.subarray((value)>>2, (value+count*64)>>2);
  3484. }
  3485. GLctx.uniformMatrix4fv(GL.uniforms[location], !!transpose, view);
  3486. }
  3487. function _glUseProgram(program) {
  3488. GLctx.useProgram(GL.programs[program]);
  3489. }
  3490. function _glVertexAttribDivisor(index, divisor) {
  3491. GLctx['vertexAttribDivisor'](index, divisor);
  3492. }
  3493. function _glVertexAttribIPointer(index, size, type, stride, ptr) {
  3494. GLctx['vertexAttribIPointer'](index, size, type, stride, ptr);
  3495. }
  3496. function _glVertexAttribPointer(index, size, type, normalized, stride, ptr) {
  3497. GLctx.vertexAttribPointer(index, size, type, !!normalized, stride, ptr);
  3498. }
  3499. function _glViewport(x0, x1, x2, x3) { GLctx['viewport'](x0, x1, x2, x3) }
  3500. function _pthread_create() {
  3501. return 6;
  3502. }
  3503. function _pthread_join() {
  3504. return 28;
  3505. }
  3506. function _setTempRet0($i) {
  3507. setTempRet0(($i) | 0);
  3508. }
  3509. var readAsmConstArgsArray=[];
  3510. function readAsmConstArgs(sigPtr, buf) {
  3511. readAsmConstArgsArray.length = 0;
  3512. var ch;
  3513. // Most arguments are i32s, so shift the buffer pointer so it is a plain
  3514. // index into HEAP32.
  3515. buf >>= 2;
  3516. while (ch = HEAPU8[sigPtr++]) {
  3517. // A double takes two 32-bit slots, and must also be aligned - the backend
  3518. // will emit padding to avoid that.
  3519. var double = ch < 105;
  3520. if (double && (buf & 1)) buf++;
  3521. readAsmConstArgsArray.push(double ? HEAPF64[buf++ >> 1] : HEAP32[buf]);
  3522. ++buf;
  3523. }
  3524. return readAsmConstArgsArray;
  3525. }
  3526. function runAndAbortIfError(func) {
  3527. try {
  3528. return func();
  3529. } catch (e) {
  3530. abort(e);
  3531. }
  3532. }
  3533. var Asyncify={State:{Normal:0,Unwinding:1,Rewinding:2},state:0,StackSize:4096,currData:null,handleSleepReturnValue:0,exportCallStack:[],callStackNameToId:{},callStackIdToName:{},callStackId:0,afterUnwind:null,asyncFinalizers:[],sleepCallbacks:[],getCallStackId:function(funcName) {
  3534. var id = Asyncify.callStackNameToId[funcName];
  3535. if (id === undefined) {
  3536. id = Asyncify.callStackId++;
  3537. Asyncify.callStackNameToId[funcName] = id;
  3538. Asyncify.callStackIdToName[id] = funcName;
  3539. }
  3540. return id;
  3541. },instrumentWasmExports:function(exports) {
  3542. var ret = {};
  3543. for (var x in exports) {
  3544. (function(x) {
  3545. var original = exports[x];
  3546. if (typeof original === 'function') {
  3547. ret[x] = function() {
  3548. Asyncify.exportCallStack.push(x);
  3549. try {
  3550. return original.apply(null, arguments);
  3551. } finally {
  3552. if (ABORT) return;
  3553. var y = Asyncify.exportCallStack.pop();
  3554. assert(y === x);
  3555. Asyncify.maybeStopUnwind();
  3556. }
  3557. };
  3558. } else {
  3559. ret[x] = original;
  3560. }
  3561. })(x);
  3562. }
  3563. return ret;
  3564. },maybeStopUnwind:function() {
  3565. if (Asyncify.currData &&
  3566. Asyncify.state === Asyncify.State.Unwinding &&
  3567. Asyncify.exportCallStack.length === 0) {
  3568. // We just finished unwinding.
  3569. Asyncify.state = Asyncify.State.Normal;
  3570. runAndAbortIfError(Module['_asyncify_stop_unwind']);
  3571. if (typeof Fibers !== 'undefined') {
  3572. Fibers.trampoline();
  3573. }
  3574. if (Asyncify.afterUnwind) {
  3575. Asyncify.afterUnwind();
  3576. Asyncify.afterUnwind = null;
  3577. }
  3578. }
  3579. },allocateData:function() {
  3580. // An asyncify data structure has three fields:
  3581. // 0 current stack pos
  3582. // 4 max stack pos
  3583. // 8 id of function at bottom of the call stack (callStackIdToName[id] == name of js function)
  3584. //
  3585. // The Asyncify ABI only interprets the first two fields, the rest is for the runtime.
  3586. // We also embed a stack in the same memory region here, right next to the structure.
  3587. // This struct is also defined as asyncify_data_t in emscripten/fiber.h
  3588. var ptr = _malloc(12 + Asyncify.StackSize);
  3589. Asyncify.setDataHeader(ptr, ptr + 12, Asyncify.StackSize);
  3590. Asyncify.setDataRewindFunc(ptr);
  3591. return ptr;
  3592. },setDataHeader:function(ptr, stack, stackSize) {
  3593. HEAP32[((ptr)>>2)] = stack;
  3594. HEAP32[(((ptr)+(4))>>2)] = stack + stackSize;
  3595. },setDataRewindFunc:function(ptr) {
  3596. var bottomOfCallStack = Asyncify.exportCallStack[0];
  3597. var rewindId = Asyncify.getCallStackId(bottomOfCallStack);
  3598. HEAP32[(((ptr)+(8))>>2)] = rewindId;
  3599. },getDataRewindFunc:function(ptr) {
  3600. var id = HEAP32[(((ptr)+(8))>>2)];
  3601. var name = Asyncify.callStackIdToName[id];
  3602. var func = Module['asm'][name];
  3603. return func;
  3604. },handleSleep:function(startAsync) {
  3605. if (ABORT) return;
  3606. noExitRuntime = true;
  3607. if (Asyncify.state === Asyncify.State.Normal) {
  3608. // Prepare to sleep. Call startAsync, and see what happens:
  3609. // if the code decided to call our callback synchronously,
  3610. // then no async operation was in fact begun, and we don't
  3611. // need to do anything.
  3612. var reachedCallback = false;
  3613. var reachedAfterCallback = false;
  3614. startAsync(function(handleSleepReturnValue) {
  3615. if (ABORT) return;
  3616. Asyncify.handleSleepReturnValue = handleSleepReturnValue || 0;
  3617. reachedCallback = true;
  3618. if (!reachedAfterCallback) {
  3619. // We are happening synchronously, so no need for async.
  3620. return;
  3621. }
  3622. Asyncify.state = Asyncify.State.Rewinding;
  3623. runAndAbortIfError(function() { Module['_asyncify_start_rewind'](Asyncify.currData) });
  3624. if (typeof Browser !== 'undefined' && Browser.mainLoop.func) {
  3625. Browser.mainLoop.resume();
  3626. }
  3627. var start = Asyncify.getDataRewindFunc(Asyncify.currData);
  3628. var asyncWasmReturnValue = start();
  3629. if (!Asyncify.currData) {
  3630. // All asynchronous execution has finished.
  3631. // `asyncWasmReturnValue` now contains the final
  3632. // return value of the exported async WASM function.
  3633. //
  3634. // Note: `asyncWasmReturnValue` is distinct from
  3635. // `Asyncify.handleSleepReturnValue`.
  3636. // `Asyncify.handleSleepReturnValue` contains the return
  3637. // value of the last C function to have executed
  3638. // `Asyncify.handleSleep()`, where as `asyncWasmReturnValue`
  3639. // contains the return value of the exported WASM function
  3640. // that may have called C functions that
  3641. // call `Asyncify.handleSleep()`.
  3642. var asyncFinalizers = Asyncify.asyncFinalizers;
  3643. Asyncify.asyncFinalizers = [];
  3644. asyncFinalizers.forEach(function(func) {
  3645. func(asyncWasmReturnValue);
  3646. });
  3647. }
  3648. });
  3649. reachedAfterCallback = true;
  3650. if (!reachedCallback) {
  3651. // A true async operation was begun; start a sleep.
  3652. Asyncify.state = Asyncify.State.Unwinding;
  3653. // TODO: reuse, don't alloc/free every sleep
  3654. Asyncify.currData = Asyncify.allocateData();
  3655. runAndAbortIfError(function() { Module['_asyncify_start_unwind'](Asyncify.currData) });
  3656. if (typeof Browser !== 'undefined' && Browser.mainLoop.func) {
  3657. Browser.mainLoop.pause();
  3658. }
  3659. }
  3660. } else if (Asyncify.state === Asyncify.State.Rewinding) {
  3661. // Stop a resume.
  3662. Asyncify.state = Asyncify.State.Normal;
  3663. runAndAbortIfError(Module['_asyncify_stop_rewind']);
  3664. _free(Asyncify.currData);
  3665. Asyncify.currData = null;
  3666. // Call all sleep callbacks now that the sleep-resume is all done.
  3667. Asyncify.sleepCallbacks.forEach(function(func) {
  3668. func();
  3669. });
  3670. } else {
  3671. abort('invalid state: ' + Asyncify.state);
  3672. }
  3673. return Asyncify.handleSleepReturnValue;
  3674. },handleAsync:function(startAsync) {
  3675. return Asyncify.handleSleep(function(wakeUp) {
  3676. // TODO: add error handling as a second param when handleSleep implements it.
  3677. startAsync().then(wakeUp);
  3678. });
  3679. }};
  3680. Module["requestFullscreen"] = function Module_requestFullscreen(lockPointer, resizeCanvas) { Browser.requestFullscreen(lockPointer, resizeCanvas) };
  3681. Module["requestAnimationFrame"] = function Module_requestAnimationFrame(func) { Browser.requestAnimationFrame(func) };
  3682. Module["setCanvasSize"] = function Module_setCanvasSize(width, height, noUpdates) { Browser.setCanvasSize(width, height, noUpdates) };
  3683. Module["pauseMainLoop"] = function Module_pauseMainLoop() { Browser.mainLoop.pause() };
  3684. Module["resumeMainLoop"] = function Module_resumeMainLoop() { Browser.mainLoop.resume() };
  3685. Module["getUserMedia"] = function Module_getUserMedia() { Browser.getUserMedia() }
  3686. Module["createContext"] = function Module_createContext(canvas, useWebGL, setInModule, webGLContextAttributes) { return Browser.createContext(canvas, useWebGL, setInModule, webGLContextAttributes) };
  3687. var GLctx;;
  3688. var miniTempWebGLFloatBuffersStorage = new Float32Array(288);
  3689. for (/**@suppress{duplicate}*/var i = 0; i < 288; ++i) {
  3690. miniTempWebGLFloatBuffers[i] = miniTempWebGLFloatBuffersStorage.subarray(0, i+1);
  3691. }
  3692. ;
  3693. var ASSERTIONS = false;
  3694. /** @type {function(string, boolean=, number=)} */
  3695. function intArrayFromString(stringy, dontAddNull, length) {
  3696. var len = length > 0 ? length : lengthBytesUTF8(stringy)+1;
  3697. var u8array = new Array(len);
  3698. var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length);
  3699. if (dontAddNull) u8array.length = numBytesWritten;
  3700. return u8array;
  3701. }
  3702. function intArrayToString(array) {
  3703. var ret = [];
  3704. for (var i = 0; i < array.length; i++) {
  3705. var chr = array[i];
  3706. if (chr > 0xFF) {
  3707. if (ASSERTIONS) {
  3708. assert(false, 'Character code ' + chr + ' (' + String.fromCharCode(chr) + ') at offset ' + i + ' not in 0x00-0xFF.');
  3709. }
  3710. chr &= 0xFF;
  3711. }
  3712. ret.push(String.fromCharCode(chr));
  3713. }
  3714. return ret.join('');
  3715. }
  3716. var asmLibraryArg = {
  3717. "__assert_fail": ___assert_fail,
  3718. "emscripten_asm_const_int": _emscripten_asm_const_int,
  3719. "emscripten_enter_soft_fullscreen": _emscripten_enter_soft_fullscreen,
  3720. "emscripten_exit_fullscreen": _emscripten_exit_fullscreen,
  3721. "emscripten_get_element_css_size": _emscripten_get_element_css_size,
  3722. "emscripten_get_pointerlock_status": _emscripten_get_pointerlock_status,
  3723. "emscripten_memcpy_big": _emscripten_memcpy_big,
  3724. "emscripten_performance_now": _emscripten_performance_now,
  3725. "emscripten_resize_heap": _emscripten_resize_heap,
  3726. "emscripten_set_canvas_element_size": _emscripten_set_canvas_element_size,
  3727. "emscripten_set_click_callback_on_thread": _emscripten_set_click_callback_on_thread,
  3728. "emscripten_set_fullscreenchange_callback_on_thread": _emscripten_set_fullscreenchange_callback_on_thread,
  3729. "emscripten_set_keydown_callback_on_thread": _emscripten_set_keydown_callback_on_thread,
  3730. "emscripten_set_keypress_callback_on_thread": _emscripten_set_keypress_callback_on_thread,
  3731. "emscripten_set_keyup_callback_on_thread": _emscripten_set_keyup_callback_on_thread,
  3732. "emscripten_set_main_loop": _emscripten_set_main_loop,
  3733. "emscripten_set_mousedown_callback_on_thread": _emscripten_set_mousedown_callback_on_thread,
  3734. "emscripten_set_mouseenter_callback_on_thread": _emscripten_set_mouseenter_callback_on_thread,
  3735. "emscripten_set_mouseleave_callback_on_thread": _emscripten_set_mouseleave_callback_on_thread,
  3736. "emscripten_set_mousemove_callback_on_thread": _emscripten_set_mousemove_callback_on_thread,
  3737. "emscripten_set_mouseup_callback_on_thread": _emscripten_set_mouseup_callback_on_thread,
  3738. "emscripten_set_pointerlockchange_callback_on_thread": _emscripten_set_pointerlockchange_callback_on_thread,
  3739. "emscripten_set_resize_callback_on_thread": _emscripten_set_resize_callback_on_thread,
  3740. "emscripten_set_wheel_callback_on_thread": _emscripten_set_wheel_callback_on_thread,
  3741. "emscripten_sleep": _emscripten_sleep,
  3742. "emscripten_webgl_create_context": _emscripten_webgl_create_context,
  3743. "emscripten_webgl_init_context_attributes": _emscripten_webgl_init_context_attributes,
  3744. "emscripten_webgl_make_context_current": _emscripten_webgl_make_context_current,
  3745. "fd_write": _fd_write,
  3746. "glActiveTexture": _glActiveTexture,
  3747. "glAttachShader": _glAttachShader,
  3748. "glBindBuffer": _glBindBuffer,
  3749. "glBindBufferRange": _glBindBufferRange,
  3750. "glBindFramebuffer": _glBindFramebuffer,
  3751. "glBindRenderbuffer": _glBindRenderbuffer,
  3752. "glBindTexture": _glBindTexture,
  3753. "glBindVertexArray": _glBindVertexArray,
  3754. "glBlendEquation": _glBlendEquation,
  3755. "glBlendFunc": _glBlendFunc,
  3756. "glBufferData": _glBufferData,
  3757. "glBufferSubData": _glBufferSubData,
  3758. "glClear": _glClear,
  3759. "glClearColor": _glClearColor,
  3760. "glCompileShader": _glCompileShader,
  3761. "glCreateProgram": _glCreateProgram,
  3762. "glCreateShader": _glCreateShader,
  3763. "glCullFace": _glCullFace,
  3764. "glDeleteProgram": _glDeleteProgram,
  3765. "glDeleteShader": _glDeleteShader,
  3766. "glDepthFunc": _glDepthFunc,
  3767. "glDisable": _glDisable,
  3768. "glDrawArrays": _glDrawArrays,
  3769. "glDrawArraysInstanced": _glDrawArraysInstanced,
  3770. "glDrawElements": _glDrawElements,
  3771. "glDrawElementsInstanced": _glDrawElementsInstanced,
  3772. "glEnable": _glEnable,
  3773. "glEnableVertexAttribArray": _glEnableVertexAttribArray,
  3774. "glFramebufferTexture2D": _glFramebufferTexture2D,
  3775. "glFrontFace": _glFrontFace,
  3776. "glGenBuffers": _glGenBuffers,
  3777. "glGenFramebuffers": _glGenFramebuffers,
  3778. "glGenTextures": _glGenTextures,
  3779. "glGenVertexArrays": _glGenVertexArrays,
  3780. "glGenerateMipmap": _glGenerateMipmap,
  3781. "glGetIntegerv": _glGetIntegerv,
  3782. "glGetProgramInfoLog": _glGetProgramInfoLog,
  3783. "glGetProgramiv": _glGetProgramiv,
  3784. "glGetShaderInfoLog": _glGetShaderInfoLog,
  3785. "glGetShaderiv": _glGetShaderiv,
  3786. "glGetUniformBlockIndex": _glGetUniformBlockIndex,
  3787. "glGetUniformLocation": _glGetUniformLocation,
  3788. "glLinkProgram": _glLinkProgram,
  3789. "glScissor": _glScissor,
  3790. "glShaderSource": _glShaderSource,
  3791. "glStencilFunc": _glStencilFunc,
  3792. "glStencilMask": _glStencilMask,
  3793. "glStencilOp": _glStencilOp,
  3794. "glTexImage2D": _glTexImage2D,
  3795. "glTexParameteri": _glTexParameteri,
  3796. "glUniform1f": _glUniform1f,
  3797. "glUniform1i": _glUniform1i,
  3798. "glUniform2f": _glUniform2f,
  3799. "glUniform3f": _glUniform3f,
  3800. "glUniform4f": _glUniform4f,
  3801. "glUniformBlockBinding": _glUniformBlockBinding,
  3802. "glUniformMatrix4fv": _glUniformMatrix4fv,
  3803. "glUseProgram": _glUseProgram,
  3804. "glVertexAttribDivisor": _glVertexAttribDivisor,
  3805. "glVertexAttribIPointer": _glVertexAttribIPointer,
  3806. "glVertexAttribPointer": _glVertexAttribPointer,
  3807. "glViewport": _glViewport,
  3808. "pthread_create": _pthread_create,
  3809. "pthread_join": _pthread_join,
  3810. "setTempRet0": _setTempRet0
  3811. };
  3812. var asm = createWasm();
  3813. /** @type {function(...*):?} */
  3814. var ___wasm_call_ctors = Module["___wasm_call_ctors"] = function() {
  3815. return (___wasm_call_ctors = Module["___wasm_call_ctors"] = Module["asm"]["__wasm_call_ctors"]).apply(null, arguments);
  3816. };
  3817. /** @type {function(...*):?} */
  3818. var _malloc = Module["_malloc"] = function() {
  3819. return (_malloc = Module["_malloc"] = Module["asm"]["malloc"]).apply(null, arguments);
  3820. };
  3821. /** @type {function(...*):?} */
  3822. var _free = Module["_free"] = function() {
  3823. return (_free = Module["_free"] = Module["asm"]["free"]).apply(null, arguments);
  3824. };
  3825. /** @type {function(...*):?} */
  3826. var _main = Module["_main"] = function() {
  3827. return (_main = Module["_main"] = Module["asm"]["main"]).apply(null, arguments);
  3828. };
  3829. /** @type {function(...*):?} */
  3830. var ___errno_location = Module["___errno_location"] = function() {
  3831. return (___errno_location = Module["___errno_location"] = Module["asm"]["__errno_location"]).apply(null, arguments);
  3832. };
  3833. /** @type {function(...*):?} */
  3834. var _ma_device_process_pcm_frames_capture__webaudio = Module["_ma_device_process_pcm_frames_capture__webaudio"] = function() {
  3835. return (_ma_device_process_pcm_frames_capture__webaudio = Module["_ma_device_process_pcm_frames_capture__webaudio"] = Module["asm"]["ma_device_process_pcm_frames_capture__webaudio"]).apply(null, arguments);
  3836. };
  3837. /** @type {function(...*):?} */
  3838. var _ma_device_process_pcm_frames_playback__webaudio = Module["_ma_device_process_pcm_frames_playback__webaudio"] = function() {
  3839. return (_ma_device_process_pcm_frames_playback__webaudio = Module["_ma_device_process_pcm_frames_playback__webaudio"] = Module["asm"]["ma_device_process_pcm_frames_playback__webaudio"]).apply(null, arguments);
  3840. };
  3841. /** @type {function(...*):?} */
  3842. var _emscripten_main_thread_process_queued_calls = Module["_emscripten_main_thread_process_queued_calls"] = function() {
  3843. return (_emscripten_main_thread_process_queued_calls = Module["_emscripten_main_thread_process_queued_calls"] = Module["asm"]["emscripten_main_thread_process_queued_calls"]).apply(null, arguments);
  3844. };
  3845. /** @type {function(...*):?} */
  3846. var _emscripten_stack_get_base = Module["_emscripten_stack_get_base"] = function() {
  3847. return (_emscripten_stack_get_base = Module["_emscripten_stack_get_base"] = Module["asm"]["emscripten_stack_get_base"]).apply(null, arguments);
  3848. };
  3849. /** @type {function(...*):?} */
  3850. var _emscripten_stack_get_end = Module["_emscripten_stack_get_end"] = function() {
  3851. return (_emscripten_stack_get_end = Module["_emscripten_stack_get_end"] = Module["asm"]["emscripten_stack_get_end"]).apply(null, arguments);
  3852. };
  3853. /** @type {function(...*):?} */
  3854. var stackSave = Module["stackSave"] = function() {
  3855. return (stackSave = Module["stackSave"] = Module["asm"]["stackSave"]).apply(null, arguments);
  3856. };
  3857. /** @type {function(...*):?} */
  3858. var stackRestore = Module["stackRestore"] = function() {
  3859. return (stackRestore = Module["stackRestore"] = Module["asm"]["stackRestore"]).apply(null, arguments);
  3860. };
  3861. /** @type {function(...*):?} */
  3862. var stackAlloc = Module["stackAlloc"] = function() {
  3863. return (stackAlloc = Module["stackAlloc"] = Module["asm"]["stackAlloc"]).apply(null, arguments);
  3864. };
  3865. /** @type {function(...*):?} */
  3866. var _emscripten_stack_set_limits = Module["_emscripten_stack_set_limits"] = function() {
  3867. return (_emscripten_stack_set_limits = Module["_emscripten_stack_set_limits"] = Module["asm"]["emscripten_stack_set_limits"]).apply(null, arguments);
  3868. };
  3869. /** @type {function(...*):?} */
  3870. var dynCall_iiii = Module["dynCall_iiii"] = function() {
  3871. return (dynCall_iiii = Module["dynCall_iiii"] = Module["asm"]["dynCall_iiii"]).apply(null, arguments);
  3872. };
  3873. /** @type {function(...*):?} */
  3874. var dynCall_v = Module["dynCall_v"] = function() {
  3875. return (dynCall_v = Module["dynCall_v"] = Module["asm"]["dynCall_v"]).apply(null, arguments);
  3876. };
  3877. /** @type {function(...*):?} */
  3878. var dynCall_viiii = Module["dynCall_viiii"] = function() {
  3879. return (dynCall_viiii = Module["dynCall_viiii"] = Module["asm"]["dynCall_viiii"]).apply(null, arguments);
  3880. };
  3881. /** @type {function(...*):?} */
  3882. var dynCall_ii = Module["dynCall_ii"] = function() {
  3883. return (dynCall_ii = Module["dynCall_ii"] = Module["asm"]["dynCall_ii"]).apply(null, arguments);
  3884. };
  3885. /** @type {function(...*):?} */
  3886. var dynCall_vi = Module["dynCall_vi"] = function() {
  3887. return (dynCall_vi = Module["dynCall_vi"] = Module["asm"]["dynCall_vi"]).apply(null, arguments);
  3888. };
  3889. /** @type {function(...*):?} */
  3890. var dynCall_iiiiii = Module["dynCall_iiiiii"] = function() {
  3891. return (dynCall_iiiiii = Module["dynCall_iiiiii"] = Module["asm"]["dynCall_iiiiii"]).apply(null, arguments);
  3892. };
  3893. /** @type {function(...*):?} */
  3894. var dynCall_vii = Module["dynCall_vii"] = function() {
  3895. return (dynCall_vii = Module["dynCall_vii"] = Module["asm"]["dynCall_vii"]).apply(null, arguments);
  3896. };
  3897. /** @type {function(...*):?} */
  3898. var dynCall_iii = Module["dynCall_iii"] = function() {
  3899. return (dynCall_iii = Module["dynCall_iii"] = Module["asm"]["dynCall_iii"]).apply(null, arguments);
  3900. };
  3901. /** @type {function(...*):?} */
  3902. var dynCall_iiiii = Module["dynCall_iiiii"] = function() {
  3903. return (dynCall_iiiii = Module["dynCall_iiiii"] = Module["asm"]["dynCall_iiiii"]).apply(null, arguments);
  3904. };
  3905. /** @type {function(...*):?} */
  3906. var dynCall_iidiiii = Module["dynCall_iidiiii"] = function() {
  3907. return (dynCall_iidiiii = Module["dynCall_iidiiii"] = Module["asm"]["dynCall_iidiiii"]).apply(null, arguments);
  3908. };
  3909. /** @type {function(...*):?} */
  3910. var dynCall_jiji = Module["dynCall_jiji"] = function() {
  3911. return (dynCall_jiji = Module["dynCall_jiji"] = Module["asm"]["dynCall_jiji"]).apply(null, arguments);
  3912. };
  3913. /** @type {function(...*):?} */
  3914. var _asyncify_start_unwind = Module["_asyncify_start_unwind"] = function() {
  3915. return (_asyncify_start_unwind = Module["_asyncify_start_unwind"] = Module["asm"]["asyncify_start_unwind"]).apply(null, arguments);
  3916. };
  3917. /** @type {function(...*):?} */
  3918. var _asyncify_stop_unwind = Module["_asyncify_stop_unwind"] = function() {
  3919. return (_asyncify_stop_unwind = Module["_asyncify_stop_unwind"] = Module["asm"]["asyncify_stop_unwind"]).apply(null, arguments);
  3920. };
  3921. /** @type {function(...*):?} */
  3922. var _asyncify_start_rewind = Module["_asyncify_start_rewind"] = function() {
  3923. return (_asyncify_start_rewind = Module["_asyncify_start_rewind"] = Module["asm"]["asyncify_start_rewind"]).apply(null, arguments);
  3924. };
  3925. /** @type {function(...*):?} */
  3926. var _asyncify_stop_rewind = Module["_asyncify_stop_rewind"] = function() {
  3927. return (_asyncify_stop_rewind = Module["_asyncify_stop_rewind"] = Module["asm"]["asyncify_stop_rewind"]).apply(null, arguments);
  3928. };
  3929. // === Auto-generated postamble setup entry stuff ===
  3930. var calledRun;
  3931. /**
  3932. * @constructor
  3933. * @this {ExitStatus}
  3934. */
  3935. function ExitStatus(status) {
  3936. this.name = "ExitStatus";
  3937. this.message = "Program terminated with exit(" + status + ")";
  3938. this.status = status;
  3939. }
  3940. var calledMain = false;
  3941. dependenciesFulfilled = function runCaller() {
  3942. // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
  3943. if (!calledRun) run();
  3944. if (!calledRun) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
  3945. };
  3946. function callMain(args) {
  3947. var entryFunction = Module['_main'];
  3948. args = args || [];
  3949. var argc = args.length+1;
  3950. var argv = stackAlloc((argc + 1) * 4);
  3951. HEAP32[argv >> 2] = allocateUTF8OnStack(thisProgram);
  3952. for (var i = 1; i < argc; i++) {
  3953. HEAP32[(argv >> 2) + i] = allocateUTF8OnStack(args[i - 1]);
  3954. }
  3955. HEAP32[(argv >> 2) + argc] = 0;
  3956. try {
  3957. var ret = entryFunction(argc, argv);
  3958. // In PROXY_TO_PTHREAD builds, we should never exit the runtime below, as
  3959. // execution is asynchronously handed off to a pthread.
  3960. // if we are saving the stack, then do not call exit, we are not
  3961. // really exiting now, just unwinding the JS stack
  3962. if (!noExitRuntime) {
  3963. // if we're not running an evented main loop, it's time to exit
  3964. exit(ret, /* implicit = */ true);
  3965. }
  3966. }
  3967. catch(e) {
  3968. if (e instanceof ExitStatus) {
  3969. // exit() throws this once it's done to make sure execution
  3970. // has been stopped completely
  3971. return;
  3972. } else if (e == 'unwind') {
  3973. // running an evented main loop, don't immediately exit
  3974. noExitRuntime = true;
  3975. return;
  3976. } else {
  3977. var toLog = e;
  3978. if (e && typeof e === 'object' && e.stack) {
  3979. toLog = [e, e.stack];
  3980. }
  3981. err('exception thrown: ' + toLog);
  3982. quit_(1, e);
  3983. }
  3984. } finally {
  3985. calledMain = true;
  3986. }
  3987. }
  3988. /** @type {function(Array=)} */
  3989. function run(args) {
  3990. args = args || arguments_;
  3991. if (runDependencies > 0) {
  3992. return;
  3993. }
  3994. preRun();
  3995. // a preRun added a dependency, run will be called later
  3996. if (runDependencies > 0) {
  3997. return;
  3998. }
  3999. function doRun() {
  4000. // run may have just been called through dependencies being fulfilled just in this very frame,
  4001. // or while the async setStatus time below was happening
  4002. if (calledRun) return;
  4003. calledRun = true;
  4004. Module['calledRun'] = true;
  4005. if (ABORT) return;
  4006. initRuntime();
  4007. preMain();
  4008. if (Module['onRuntimeInitialized']) Module['onRuntimeInitialized']();
  4009. if (shouldRunNow) callMain(args);
  4010. postRun();
  4011. }
  4012. if (Module['setStatus']) {
  4013. Module['setStatus']('Running...');
  4014. setTimeout(function() {
  4015. setTimeout(function() {
  4016. Module['setStatus']('');
  4017. }, 1);
  4018. doRun();
  4019. }, 1);
  4020. } else
  4021. {
  4022. doRun();
  4023. }
  4024. }
  4025. Module['run'] = run;
  4026. /** @param {boolean|number=} implicit */
  4027. function exit(status, implicit) {
  4028. // if this is just main exit-ing implicitly, and the status is 0, then we
  4029. // don't need to do anything here and can just leave. if the status is
  4030. // non-zero, though, then we need to report it.
  4031. // (we may have warned about this earlier, if a situation justifies doing so)
  4032. if (implicit && noExitRuntime && status === 0) {
  4033. return;
  4034. }
  4035. if (noExitRuntime) {
  4036. } else {
  4037. EXITSTATUS = status;
  4038. exitRuntime();
  4039. if (Module['onExit']) Module['onExit'](status);
  4040. ABORT = true;
  4041. }
  4042. quit_(status, new ExitStatus(status));
  4043. }
  4044. if (Module['preInit']) {
  4045. if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];
  4046. while (Module['preInit'].length > 0) {
  4047. Module['preInit'].pop()();
  4048. }
  4049. }
  4050. // shouldRunNow refers to calling main(), not run().
  4051. var shouldRunNow = true;
  4052. if (Module['noInitialRun']) shouldRunNow = false;
  4053. noExitRuntime = true;
  4054. run();